Hi everyone. We’ve been using WordPress and the wp-discourse plugin for the past several months and it’s working great.
Here’s how it currently works: Someone signs up via our WordPress site and then when/if they visit the forum part of our site and click the blue Login button, Discourse automatically creates an account for them.
This all works great.
So, here’s the only problem – If they don’t go over to the forum section and click the Login button, they don’t get an account setup for them in Discourse and they don’t get all of Discourse’s awesome “Summary” emails etc etc. We really want our new users to be enticed to participate in the forums right off the bat.
What we’d like to do is automatically setup an account in Discourse for them upon them signing up for WordPress. I can use the API to create a Discourse user, but I’m just not sure if I do this whether that account will “play well” with the wp-discourse plugin sso code.
Just wondering if anyone has already been down this road and wants to share how they did it?
I see this lamentation frequently. Would adding sync_sso to the WordPress account creation code create the account without requiring the user to come over to Discourse and click the login button? It seems that every client I have worked with who’s used SSO has complained about this.
This could be added to the plugin. I can think of two ways of approaching it:
automatically create a Discourse user when a WordPress user is created
or
adding a WordPress shortcode that would create a login link to the forum. The link would only appear for logged in WordPress users who do not yet have an account on Discourse. The text could be set to something like ‘Join Our Forum’. When a user clicked on the link, a Discourse user would be created for them and they could be either redirected back to WordPress, or to a specific page on Discourse.
Either approach would work. The second one would be a little easier to implement - it wouldn’t require any changes to the plugin’s existing code.
An ugly, but easy hack we’ve been using is to embed Discourse in an invisible iframe on the registration success page. Since no user interaction is required to trigger the login (assuming your instance is login required or you directly embed the SSO URL), this should be enough to create the account
[quote=“Simon_Cossar, post:5, topic:58494”]
automatically create a Discourse user when a WordPress user is created
[/quote] This one seems way more user friendly to me. Keep in in mind for a future sprint
Thanks @fefrei and @Grex315 for the iframe idea. I’m going to try following those instructions and see how it goes.
On a related note – Is there an admin setting to turn off the feature that requires people to activate their brand new Discourse account via an email link? I couldn’t find one. For us, it just feels like one more hoop for our users to jump through to have to click that link.
Instead of showing the <embed> via the wordpress login hook, I just hardcoded the <embed> statement into the bottom of our “Thanks for signing up!” page in WordPress since that gets shown right after they join and is only shown once. (This could be a simpler approach for people who don’t want to have to deal with adding php code.)
There isn’t an admin setting, but you can turn it off with a bit of code.
If a site is using the default WordPress login setup, then users shouldn’t be having to reverify their email with Discourse. For sites that are logging users in differently, for example through a front-end login form, verification is required.
There are some security risks in allowing users to create a Discourse account through SSO without first confirming that they control the email address. The biggest risk that I can see is if there are accounts that exist on your Discourse site that are not yet associated with a WordPress user id. For example, if there is an admin account on a Discourse site with the email address [email protected] that has not been logged into through SSO, a user could create an account through WordPress with the unverified email address [email protected] and then login to Discourse as that admin user.
To completely remove the require_activation flag, add something like this to your theme’s functions.php file.
// Replace 'my_prefix' with your site prefix.
add_filter( 'discourse_email_verification', 'my_prefix_discourse_email_verification' );
function my_prefix_discourse_email_verification( $require_activation, $user_id ) {
return false;
}
Other than displaying an error in the console, the embedding method seems to work well.
NOTE: The WP Discourse plugin now has code built into it for creating and syncing users on login when SSO is enabled. It does not automatically log users into Discourse, but for most use cases that shouldn’t be necessary.
Creating a user automatically can be done without embedding the /session/sso URL by adding something like this to your functions.php file. Possibly this could be added as an option to the plugin.
add_action( 'wp_login', 'my_prefix_discourse_login', 10, 2 );
function my_prefix_discourse_login( $user_login, $user ) {
if ( class_exists( '\WPDiscourse\Utilities\Utilities' ) ) {
$discourse_options = \WPDiscourse\Utilities\Utilities::get_options();
if ( ! empty( $discourse_options['enable-sso'] ) && 1 === intval( $discourse_options['enable-sso'] ) ) {
// Set to where you want to redirect to. To redirect back to WordPress instead of Discourse,
// you need to enable the Discourse setting 'sso allows all return paths'.
$redirect = home_url( '/' );
$sso_url = ! empty( $discourse_options['url'] ) ? $discourse_options['url'] . '/session/sso?return_path=' . $redirect : '';
$query_string = parse_url( wp_get_referer(), PHP_URL_QUERY );
$query_params = [];
parse_str( $query_string, $query_params );
// Make sure it's the login hasn't been initiated by clicking on a SSO login link.
$sso_referer = ! empty( $query_params['redirect_to'] ) && preg_match( '/^\/\?sso/', $query_params['redirect_to'] );
if ( empty( get_user_meta( $user->ID, 'discourse_email_not_verified', true ) ) && ! $sso_referer ) {
wp_redirect( esc_url( $sso_url ) );
exit;
}
}
}