Syncing login status between WordPress and Discourse, Discourse SSO provider


#1

I’m using the WP Discourse plugin to connect my WordPress and Discourse sites, using Discourse as the SSO provider, I plan to disable WP login page and only rely on Discourse’s user authentication. Everything worked well except login status is not synced in WordPress. Either login or logout from Discourse, my login status in WordPress doesn’t change automatically, for log in, I have to click the Login with Discourse link (https://example.com/?discourse_sso=1). Same thing for logout, have to use WP’s logout link.

Settings in WP Discourse plugin:
Set SSO Secret Key
Checked Enable SSO Client
Checked Add Login Link
Checked Sync Existing Users by Email

Settings in Discourse:
Checked enable sso provider
Set sso secret

WP version: 4.8.1
WP Discourse plugin version: 1.4.3
Discourse version: 1.9.0.beta5

Is this the expected behavior? If so, what’s the the best way to enable login status syncing?

Thanks!


(Simon Cossar) #2

Yes, it is, but there are a couple of workarounds. You can sync logout between Discourse and WordPress by adding a URL like this to the Discourse logout_redirect setting:
http://my-wp-blog.com/?request=logout

The easiest way to get users logged in on WordPress when they visit the site from Discourse is to link to the site on Discourse with an SSO link. You can get the form of the URL by inspecting the ‘Login With Discourse’ link on your WordPress login page. It should look something like this:

<a href="http://wordpress.dev/?discourse_sso=1&redirect_to=http://wordpress.dev/">Log in with Discourse</a>

Change the value of the redirect_to parameter to get users to a specific page.

A Discourse plugin could probably be developed that would automatically sync login with WordPress. It’s not something that can be accomplished through the WP Discourse plugin.


#3

Got it. Thanks for the explanation!


(Lew Grothe) #4

We’re in the process of adding a WordPress front end to our Discourse forum. WordPress is client SSO to Discourse (we only log in through Discourse).

I want/need the is_user_logged_in state in WordPress to be able to toggle some features on the WordPress site for folks who are logged in (and keep private from those who are not).

All works well when an individual is logged in and logs out on each machine/browser. The problem arises when a member logs in on one machine, goes to another browser or mobile device and logs in using the same account there (actually is simply identified as logged in and everything is copacetic) and then logs out there.

The original WP instance will not see the user as logged out (state for Discourse is maintained on a user level, not session).

Keeping sessions separate would probably be the best solution but seems an architectural stretch for the Discourse API.

A hack that would work for our purposes would be to simply query the Discourse server (from WP) and logout if the user has been logged out. This could be done either on a timed basis or on a page refresh on WP (e.g. in functions.php or header.php for the theme).

Am I missing something? Has someone tried something like this and willing to share their experience?


(Simon Cossar) #5

Is the basic issue you’re trying to solve that when a user is logged out on WordPress, you want them to be logged out in all WordPress sessions? wp_ajax_destroy_sessions() | Function | WordPress Developer Resources

Edit: I think you could use the logic that’s in the wp_ajax_destroy_sessions function to write your own function that would do the same thing. The WP Discourse plugin should have an action hook added to it that fires right before it calls wp_logout. I can get that added in the next update. You should be able to hook into that action to log users out from all sessions.


(Lew Grothe) #6

Great idea - this would work.

Since logging out of discourse would call wp_logout() (via logout_redirect in the Discourse admin), couldn’t I just add an action on wp_logout() for the user and not rely on the WP Discourse plugin’s action hook?

Seems either way would work but we don’t expect ever to have a user logged into the WP instance in any other way…


(Simon Cossar) #7

You could try that. I think that the wp_logout action might be called too late for this to work.

wp_logout is a pluggable function. If you define your own wp_logout function, your function will be called instead of the function defined by WordPress. You could probably create a function for this that logs the user out on all devices.


(Lew Grothe) #8

I’m ALMOST there - thanx for all your help so far… going on our production site today…

I overwrote wp_logout to do exactly as you said (destroy all sessions for a user) and it works the way we want with the wp_discourse plugin now.

Since I went this far, I also solved another problem I was having to hack on the wp_discourse plugin to solve for our community,. Our designer wanted to have existing members remain on the discourse forum when they logged (instead of the WP home page) since they’re familiar with that behavior now (pre WP front end). I had hacked the redirect in the wp_discourse plugin to support this behavior (by a url GET parameter) but, since I was already playing with pluggable functions, I just added my code to wp_login and now I don’t have to have any changes to wp_discourse.

I had thought about suggesting a feature request or pull request for our hacked wp_discourse plugin to do this but it seems to me there are VERY few folks who will want either of these behaviors as it’s outside the regular model of how login/logout works and, as with most features like this it will likely add confusion and/or support problems. So, we’re fine on the unmodified plugin for now. (you’re welcome :grinning:).

Thanks again for all your help and creating a great plugin for us…