Hello. So in searching some other threads here, it seems like the expected behavior is this:
Someone is reading a thread in Discourse and decided to login so they click the Login button
They pop over to WordPress where they login
They are redirected back to the Discourse thread that they were reading
That sounds great! In our case, this isn’t working I think because we use the MemberMouse plugin which forces people to a certain “welcome” URL after logging in. BUT, I can bypass that with a filter MemberMouse provides.
The only problem, is that the URL of the Discourse topic the person was reading doesn’t seem to be passed to WordPress.
E.g. Let’s say I’m in this topic in Discourse: https://forums.gemsociety.org/t/any-brazil-company-which-sold-rough-faceting-amethyst-citerine-and-amertine/1246
And I click the Login button in Discourse
I get sent to this URL: https://www.gemsociety.org/login/?redirect_to=%2Flogin%3Fsso%3Dbm9uY2U9Y2IwZGE0NmRlMGM0YTlhOGM1OTc4OGU0NGRjOGU3MDkmcmV0dXJu%250BX3Nzb191cmw9aHR0cCUzQSUyRiUyRmZvcnVtcy5nZW1zb2NpZXR5Lm9yZyUy%250BRnNlc3Npb24lMkZzc29fbG9naW4%253D%250B%26sig%3D419ba4dfda93d068c81470cf32e4aec633217047728a9bca514bbae3891cffde
Nowhere in that big string do I find the URL the person was reading in Discourse (/any-brazil-company…/).
So, I’m a little confused here. Any thoughts? Thanks!
The sso return path is saved on Discourse as the value of the nonce key. If you can find a way to get your WordPress site to redirect back to Discourse (/session/sso_login?) with the sso params users should get redirected to the page they clicked the login link on.
Right, that’s not going to work. If you look here: https://github.com/discourse/wp-discourse/blob/master/lib/sso-provider/discourse-sso.php#L146 you can see what needs to happen. If the sso and sig parameters are in the query_vars and a user is not logged in, they are redirected to the WordPress login URL with the SSO request from Discourse set as the redirect parameter. It seems like the MemberMouse plugin is overriding that redirect.
Somehow, you need to preserve the redirect (the parameter from this line: $login = wp_login_url( esc_url_raw( $redirect ) ); and redirect to it after MemberMouse has done its work. The request should then be processed by the part of the sso_parse_request function that begins here:
Now when someone comes into the forum; clicks the blue Login button; logs into wordpress by typing in their username/pw; they are redirected back to thread they were at in Discourse.
I think this is going to be a huge win for people who come in via the Discourse emails e.g. and want to participate in the thread. Previously, they’d lose track of where they were since they didn’t get redirected back to the thread.
For anyone else looking into this – This “redirecting back to where you were” behavior works (thx to the WP-Discourse plugin) in the scenario #1 where you are already logged into WordPress.
But it’s scenario #2 where you need to login to WordPress that you are not automatically redirected back to the forum thread where you were. This is what I added in myself thanks to @simon 's help.
I thought it was due to my membership plugin but I actually just think the scenario #2 redirect functionality doesn’t exist in the WP-Discourse plugin. I could be wrong about this, feel free to correct me!
When SSO is enabled, clicking the login link on Discourse should automatically redirect users back to the Discourse page that they clicked the login link on. If this isn’t working for you, can you give some details about where you are seeing the problem?
Hi Richard. It’s been a while since I worked on this and things seem to be changing from time to time in the discourse plugin (new and better functions keep cropping up) but this is what I did way back them and it still works for us.
We use the wordpress plugin membermouse. And membermouse is written in such a way that after you login, you get redirected to a specific wordpress “welcome member!” page. So this functionality was overriding discourse’s attempt to redirect you back to where you were in discourse.
membermouse has a filter called mm_login_redirect where you can change membermouse’s behavior of redirecting the user to that “welcome member!” page. Below is the php code I wrote for that filter.
// If the person came from the discourse forum, push them back after logging in
function my_mm_login_redirect( $infoObj ) {
$current_user = $infoObj->user;
if ( is_wp_error($current_user) ) return('');
$user_id = $current_user->ID;
if ( @$_COOKIE['detected_forum_referal'] != '' ) {
// Payload and signature.
$payload = @$_COOKIE['mm_cookie_sso'];
$sig = @$_COOKIE['mm_cookie_sig'];
// Change %0B back to %0A.
$payload = rawurldecode( str_replace( '%0B', '%0A', rawurlencode( $payload ) ) );
// Validate signature.
$sso_secret = '###################';
$sso = new \WPDiscourse\SSO\SSO( $sso_secret );
if ( ! ( $sso->validate( $payload, $sig ) ) ) {
return '';
}
$nonce = $sso->get_nonce( $payload );
$params = array(
'nonce' => $nonce,
'username' => $current_user->user_login,
'email' => $current_user->user_email,
'external_id' => $user_id,
);
$params = apply_filters( 'wpdc_sso_params', $params, $current_user );
$q = $sso->build_login_string( $params );
do_action( 'wpdc_sso_provider_before_sso_redirect', $user_id, $current_user );
// Redirect back to Discourse.
return('https://YOURFORMURLHERE' . '/session/sso_login?' . $q);
}
return('');
}
add_filter( 'mm_login_redirect', 'my_mm_login_redirect', 10, 1 );
Btw, I should reiterate that there may be a better way to accomplish than my code above. It’s just what worked at the time that I needed to solve this issue.
Thanks for doing this! I installed the Membermouse plugin in my development environment today. Getting the redirect back to Discourse is harder than I expected. I don’t think there’s any reason to change the way you are doing it, but here’s an alternate approach. It at least shows how the plugin expects things to work. Generally, it should be possible to do this by hooking into the WordPress login_redirect filter and getting the Discourse redirect_to parameter from that filter’s $request parameter. This can’t be done with Membermouse though.
This function depends on being able to get the HTTP_REFERER with wp_get_referer. The referer may not always be available. If it isn’t, the user will be redirected to the default Membermouse redirect. I have only tested this in my development environment.
@simon, I did a test and that function you provided definitely works. So much more compact and efficient. Thanks! (@RGJ you should definitely give that function a try.)