Discourse with PHP main page


(Maestro Magnifico) #1

I want to integrate Discourse into my PHP main page. Because I don’t code Ruby on Rails. How can I catch Discourse session with PHP? All I need is a current user id, basically. I will be able to get everything else from DB manually.


(Jeff Atwood) #2

So you want single sign on? There is an official SSO topic on meta.


(Maestro Magnifico) #3

Just have read what SSO is. No, it’s not what I want. SSO allows users to login via your site. But I want to find out if user already logged in or not. I need to catch user’s id from existing Discourse session. Example:
My site is here:

example.com

My Discourse is here:

forum.example.com

Somehow I need to catch $_SESSION from forum subdomain when users visit example.com. And do it with PHP. Is it possible?


(Jens Maier) #4

(Maestro Magnifico) #5

Okay, so I can’t get it via PHP. I can get it only via AJAX and then pass to PHP? This sounds like a terrible idea! JS can be easily hacked to pass admin’s id to PHP, for example, and PHP will return page with tools for admin only. Maybe I shouldn’t use PHP then in the first place? What’s the safer way to catch Discourse session on root domain? I can learn new stuff, so hit me hard.

I want to create a lot of things on root domain that will require user’s id from my Discourse session - shoutbox, comments for news feed, upload video or edit twitch channels list - last two should be allowed only for staff.


(Jens Maier) #6

What? No! Where did I ever mention AJAX? :open_mouth:

In the suggested setup, the PHP script on discourse.example.com interacts both with Discourse and the PHP application; it gets the user’s Discourse session from the cookie, the user’s PHP session from the authenticated query string and copies all relevant session information from Discourse’s database into the PHP app’s database. Except for a redirect back to the PHP app, it doesn’t emit anything to the user.

Alternatively, serialize the user’s session data, add a timestamp, encrypt and authenticate it, then redirect the user back to the PHP app with the encrypted session info in the query. The PHP app can authenticate and decrypt the packet and copy the contents into its own database and/or the user’s session.

However, at that point you might just enable Discourse’s OAuth provider and use that…


(Maestro Magnifico) #7

Not you, eviltrout posted AJAX aproach earlier in topic you linked.

I just didn’t got your suggested setup at first. Must be language barier or stupidity. :smile: Got it now, sounds simple, thanks! I’ll try upload some php script inside of my container now and run it. I guess this aproach means that this script will die after rebuilding app, but it’s not a biggie.


(Jens Maier) #8

Biggest problem will be that the container doesn’t have PHP installed… yet another thing you’d need to get done in your app.yml each time the container is rebuilt.

The way I intended this to work was to run another webserver in front of Discourse, since that’s what the other topic’s original poster wanted. With that in place, you don’t need to store the PHP script in Discourse’s container; instead you can tell the frontend webserver to proxy requests for discourse.example.com through to Discourse, unless it’s a request for discourse.example.com/shim which it should serve itself.

An Apache config might look like this:

<VirtualHost *:80>
    ServerName discourse.example.com

    Alias /shim/ "/var/www/example.com/htdocs/shim/"
    <Directory "/var/www/example.com/htdocs/shim/">
        Require all granted
    </Directory>

    RewriteEngine on
    RewriteRule ^/shim/(.*)$ /shim/$1 [PT,QSA,L]
    RewriteRule ^/ balancer://unicorns%{REQUEST_URI} [P,QSA,L]
</VirtualHost>

The PT flag tells Apache to hand the rewritten URL back to the URL mapping engine where it gets picked up by Alias.


403 forbidden after installation
Hello World plugin
Can't make Discourse accessible through Apache
(Maestro Magnifico) #9

Well, yea… I tried different solution now, but I failed. I tried to setup proxy between host’s Nginx on port 4003 and container’s Apache on port 4004. I have Discourse in multisite config now, it uses ports 4001 and 4002. I checked container’s Nginx configs - those ports are not even in the configs. So I have no idea how Discourse doing this voodoo magic. Using Apache as a front-end of Discourse doesn’t sound right at all…


Uhhh… this drills my brain. Why can’t we have some token protected API end-point for geting user info out of Discourse? :yuno:


(Jens Maier) #10

Yeah, check the expose option in your app.yml. The docker daemon itself will listen on the host’s public interfaces at the first port and will forward incoming traffic to the container at the second port. For example, you should be able to set expose 4000:80, run iptables -A INPUT ! -i lo -p tcp --dport 4000 -j DROP and proxy to 127.0.0.1:4000. (The iptables command will prevent direct outside access to Discourse.)

I find this… strange, considering docker also manages several firewall chains and it should be possible to simply forward traffic from host port A to container port B via DNAT – but what can you do. :neutral_face:

Works for me, tho. :relieved:

Anyways, I posted that Apache config because that’s what I know best. I’m sure that nginx can be configured in a similar way, but I’ve worked with that server a grand total of never and I was just too darn lazy to rebuild my Apache config in nginx. :sweat_smile:


(Maestro Magnifico) #11

There is a FastCGI thing for Nginx that allows you to use PHP. I’ll try it tomorow.


(Kane York) #12

@Maestra_Powers, @elberet:

Check out the updated “other websites on the same machine” guide, I updated it to have the container expose a Unix socket:


(Maestro Magnifico) #13

Thanks for tutorial, it looks more safe than I have right now. But this is not the thing we’re descussing here. We’re trying to figure out how to run “other website” located inside of Docker container with Discourse. Although there’s probably much more easier way of doing this by adding custom Ruby script to Discourse as a plugin or something.


(Kane York) #14

…Why, I must ask, must it be inside?


(Maestro Magnifico) #15

Because we’re trying to get user’s Discourse session. If Discourse located here:

discourse.example.com

And “other website” here:

example.com

Then there’s no way you can check from root domain if user loged in or not. Discourse doesn’t provide this function, so we’re trying to run our own script inside of container that will “talk” with other script on host. Their communication should be protected of course. Easiest way of doing this that I see so far - store password in both scripts and compare them all the time.


(Maestro Magnifico) #16

There’s deffinetly is an “end-point” for this somewhere, if you look at source code. How can I get this?