SSO credentials validity / forced logout

What expectation should I have for how long a user can stay logged on before being prompted again?

I have implemented my own check in functions.php, integrating with the SSO plugin for WordPress. My logic seems pretty simple but I just noticed that a member who had a declined credit card (hence removing the user tag that my logic checks) was able to access my forum today. On further checking she last logged on a couple of days ago and, I guess, still seems to be. Her last logon date for WordPress is also a few days back.

Is it expected that her cached credentials should still be working. If so, is there any way to control the validity of the token and/or respond to a webhook to force a logout?

Thank you.

1 Like

This is controlled by the Discourse maximum session age site setting. It sets the number of hours that users will remail logged into your site for. It defaults to 1440 hours (60 days.) You could try setting this to a lower value. If you set it too low it will seem like a bug to your users.

This makes sense. You can log users out manually by going to their Discourse Admin page and clicking the ā€˜Log Outā€™ button that youā€™ll see near the top-right of the page. Another option for controlling this would be to add some code to your WordPress site that logs users out of Discourse when a membership expires.

2 Likes

Much appreciated, Simon. While I think 60 days is a too long for my scenarios (these are paying members and so they have an expectation weā€™d check they are still valid members), I do agree that reducing it too much can be a pain.

The final suggestion (find a way to log them out of Discourse when membership ends) is what I will research. I had seen the manual logout option but looking to totally automate all of this, so that seems like the right path.

Thanks again.

1 Like

Hmmā€¦ the description of the site setting says (emphasis mine):

User will remain logged in for n hours since last visit

If I understand correctly, could remain logged in forever if they continue to visit the site periodically even after they lose their SSO credentials. For example, if the setting were set to 72 hours, as long as they continued to visit the site every day or two, theyā€™d remain logged in. Am I interpreting that correctly?

2 Likes

Yes, that is true in my experience. There is no absolute timeout that forcefully logs someone out after a fixed period of time.

1 Like

So is the implication of this that if someone cancels my membership and I want to be sure they canā€™t access my forum I will need to forcefully log them off (manually or via an API call)?

1 Like

Yes that is the recommendation

1 Like

Thank you. Having just switched from a Facebook group (which required manually removing members when they cancelled their subscriptions) itā€™s unfortunate that, with Discourse, I will still have a manual process to ensure cancelled members canā€™t access my forum. That leads to a question.

Is there any non-manual mechanism - however creative - where I can ensure a user who no longer has a valid account i.e s/he cannot log on, will be forcefully logged out of Discourse?

It does seem logically weird to have the SSO mechanism block users from logging on (recognizing the fact they donā€™t have a valid account), but if they simply access the forum on a regular basis (less than the timeout) they can access the forum for as long as they like, until I log them off manually.

I guess my final option, potentially, is to write a plugin that will call a Discourse API to log them out when they cancel.

Open to any and all ideas here. As you can tell, I REALLY want to avoid having to do this manually :slight_smile:

Thank you.

You can make an API request to /admin/users/<discourse_user_id>/log_out. The WP Discourse plugin uses this route to sync logging out of WordPress with Discourse. You could probably copy most of the code from this function: https://github.com/discourse/wp-discourse/blob/master/lib/sso-provider/discourse-sso.php#L205.

1 Like

Much appreciated, Simon. I will take a look.

Stepping back though, does this not seem like something of a problem? I guess we can debate the importance of this, but having a platform where users can just continue to access a forum endlessly, even when they no longer have a valid account, is not something I have seen elsewhere.

I can perhaps buy the notion that itā€™s WordPress, rather than Discourse, which is the authoritative source here. So that probably points the finger at the SSO plugin as the best place to locate some logic.

Curious to know the overall thinking here. Iā€™d like to think the scenario is a valid one (force logout after a certain period of time or based on a WordPress account becoming ā€œinvalidā€), no?

Just brainstorming here since I would like to avoid manual steps - but also want to avoid writing code, if I can :slight_smile:

Yes, this will need to be handled by WordPress. I think it would make sense for the WP Discourse plugin to log users out of Discourse when they are deleted on WordPress, but Iā€™m not sure that this would solve your problem. My assumption is that when a userā€™s membership expires on your site, the user isnā€™t deleted from your WordPress site. To handle the case of logging a user out of Discourse when their membership expires, you will probably need to add some code to your site that hooks into whatever action is fired by your membership plugin when a membership expires.

1 Like

Thank you again, @simon. Your points make sense, but forgive me if I carry on for one more pass :slight_smile:

It seems to be that there are two factors at play here - the validity of an account (namely, are they an active member) and the validity of a token in Discourse.

For the first of these I absolutely agree that WordPress should own this and, as time allows, I will investigate.

However, thereā€™s also the question of an active/valid token on the Discourse side. I understand that this might not be a high priority, but I can see some logic in an option (probably defaulting to off) which has a ā€œforce logonā€ timeframe, namely after x days the users logon token expires, regardless of whether s/he logged on recently.

Again, I am very much brainstorming here, but can see some value in forcing a logout as an option, independent of whether the user has a valid account.

Iā€™m trying to do this via a web link, as Iā€™m not using WordPress. Should I be able to do it with something like this?

https://community.mysite.com/admin/users/100004/log_out

It comes up with a 404 error for me, and the user is not logged out.

If I can get a URL to work Iā€™m hoping to force logout using a curl or file_get_contents command in PHPā€¦

You need to make an authenticated POST request to the route. You could set this up to logout users when they click a link, but you will have to handle the request on the server.

Thanks! Authenticated, eh? Doing some research on this, looks like an authenticated post from PHP sends something like this content in the header:

'Authorization: OAuth '.$accesstoken;

There are some clues out there which Iā€™ll continue to research.

But it would be great if someone had a snippet of PHP code which worked! The example in https://docs.discourse.org/ authentication section returns a syntax error for meā€¦ oh wait, thatā€™s a Unix command!

Iā€™ll welcome any clues that will help for PHP!

The link from my previous post should be enough to get you started: https://github.com/discourse/wp-discourse/blob/master/lib/sso-provider/discourse-sso.php#L205. Assuming you are not making the request from a WordPress site, youā€™ll need to figure out another way of making the wp_remote_post request.

1 Like

I think Iā€™m close, using simple PHP commands. The code is below. The username choice came from this post.

Iā€™m getting this responseā€¦ does this mean anything to anyone? Seems like an SSL protocol version thing?

error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

Here is my code:

    $url = "https://community.mysite.com/admin/users/100004/log_out";
    $headers = array( 'Api-Key' => 'd412mylongadminkeyaadcd',
    				  'Api-Username' => 'system',
    				  );

	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);

[edit: added these lines too, no change:]
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
[/edit]

	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $data = curl_exec($ch);
    if (curl_errno($ch)) {
        echo curl_error($ch);
    }
    curl_close($ch);

Since you are on WordPress, you could try making the request with the wp_remote_post function. That way you donā€™t have to deal with the curl options.

1 Like

Thanks, but I am not using WordPress. Iā€™m trying to do this in PHP in a membership manager I built myself over the last decade.

Looks like your php library didnā€™t like your discourse https cert. Iā€™d Google for that error.

1 Like