Create user automatically in Discourse when they sign up in Wordpress?

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? :slight_smile:

13 Likes

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.

4 Likes

@simon … The new membership module functionality?

1 Like

It can be done. We do it.
A new user is created in WP and automatically added to Discourse (and even allocated to specific groups).

I don’t know technically how it’s executed because I didn’t do it, but @riking talked my devs through it.

7 Likes

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.

1 Like

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 :slight_smile:

7 Likes

Been using the same as @fefrei. Using an iFrame but I do it on login. You can find the details on that one in this guide part C.

https://meta.discourse.org/t/wordpress-integration-guide/27531

3 Likes

[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 :wink:

2 Likes

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.

1 Like

Just wanted to come back and say that I did the iframe trick and it’s working. Couple of notes in case it’s helpful for anyone:

  1. I went with <embed> instead <iframe> based on the note I saw here

  2. 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.)

Thanks for the help!

3 Likes

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 admin@example.com that has not been logged into through SSO, a user could create an account through WordPress with the unverified email address admin@example.com 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;
}
3 Likes

Your security warning is very helpful. Definitely something to pause and think about. Thx!

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;
            }
        }
    }
8 Likes

Hi,
I have already done this, May be I can do this for anyone who need this. I am going to launch an addon premium plugin for this soon.

I thought that with SSO Discourse would trust the SSO provider to validate email addresses. Did you solve this too?

The problem is that in many cases WordPress isn’t validating the user’s email address. The wp-discourse plugin tries to validate the email address, but it can only do this if the default WordPress registration flow is followed. It does this by overriding the WordPress ‘new_user_notification’ email to include an email verification key.

If the email address can’t be verified, the plugin is setting the parameter require_activation to true in the SSO parameters that are send from WordPress to Discourse.

This can be over ridden with the discourse_email_verification filter.

It’s also possible to validate the email for a single user by deleting the discourse_email_not_verified user_metadata for a user. This could be done after some event that occurs that allows you to trust the user, for example, after they make a purchase on a Woocommerce site.

This has been added as an option to the plugin in the latest release. See: WP Discourse 1.3.0 Release - #3 by simon for details about it.

4 Likes

How do we find out what the site prefix is?

The site prefix is just a unique key that you use to prefix functions on your site. It’s used to avoid naming collisions when PHP namespaces aren’t being used. You can set it to anything that’s allowable in a PHP function name., for example matt_chm_discourse_email_verification.

1 Like

Thanks for clarifying!

1 Like