Discourse members being logged out - how to fix?

Hi, I’m getting word that several of my forum members are getting logged out automatically after 20-30 minutes.

I use SSO so I’m wondering if the issue could be something with them logging into the main site, then going into Discourse (which starts a new session there?), then going back to the main site (which means Discourse is idle), and then going back into Discourse and somehow being logged out.

(That doesn’t quite make sense, though, because every time they go into Discourse, it should set the “idle timeout” to 0 again, right?)

I found a couple of threads about timeouts etc. here in meta but none of them seem to have a clear answer.

Question: is there a setting to prevent members from being logged out until they are idle for X period? I can’t seem to find it.

I do see in my Discourse settings that I have my “maximum session age” set to 1 hour, but I don’t think that really makes any difference with an SSO implementation, does it? (Note that when a member logs out on my main site, I send a /logout message to Discourse, just to keep everything clean. And whenever a member does any activity in Discourse, I update the last-activity time on my main site, so it isn’t the main site timing out. I’m adding additional debugging code now to confirm that this is all working as it should.)

Thanks
E

1 Like

It does apply to SSO, so that’s likely the source of your issue. After 1 hour of inactivity, the Discourse session will be terminated and users will have to reauthenticate with SSO.

1 Like

That’s fine, and totally okay… after 1 hr of inactivity, they should be logged out.

The problem is that I’m getting reports of people being logged out after 20-30 minutes.

Is there a setting for that 1 hour idle timeout? As I mentioned in my original post, I can’t find it… and that seems like the first place to check, no?

Just to rule out the most obvious cause… is it possible that people are mistaken about the exact time? 30 minutes and 1 hour are not that different :wink:

To continue debugging this, I would suggest the next step is to look into the data available in the user_auth_tokens and user_auth_token_logs tables. They contain all the information about session tokens and expiration.

3 Likes

Yes, it’s the one you mentioned in the OP

1 Like

Agreed :wink: I’m testing it right now - logging into my site, going to the forums, and then leaving the browser alone!

Thank you for the tips on the db tables, I’ll investigate further.

1 Like

Hmm. As people use the forums and read topics, etc., if they do something that generates an action (create_post, create_topic, edit_post, etc) then I get a message via the webhook. This tells the main site that they’re still active, so I can update the ‘Last Click’ value on their session, preventing a logout. As it should. All good.

However, if a member is just reading messages for a while… their Discourse idle time is being reset every time they do something (which is good), but my main site never receives any webhook messages indicating the user is active, so after 1 hour without any activity (it looks like they went to forums and walked away from the computer) the main site assumes they’re toast and logs them out.

It seems like there’s a hole in the logic here. For a proper SSO implementation, shouldn’t there be a way for Discourse to tell me if a user’s session is active (even if they are just reading)? Perhaps Discourse should be sending a ping every 5 minutes if the member is active but hasn’t generated any other webhook messages.

Or maybe when my site thinks a user has timed out, I should call Discourse and ask if the user is active over there. Is there a way to do that? (I see Is there an endpoint to check if a user is logged in but I can’t quite tell if that’s what I want, and /session/current.json isn’t in the API docs.) That will generate a ton of API calls, though-- I log off ~15-20 users every minute on my site for inactivity, so that would be calling for each one (and possibly more than one call, if I don’t have a local cache of their Discourse ID).

Friends, what do y’all think/advise?

Every profile endpoint has a last_seen value, which you could use.

I don’t think I’ve seen this kind of setup in any SSO protocols, and we haven’t had requests for things like this. More commonly people would keep the two systems independent.

If you really wanted to create a webhook for ‘user seen’, you might be able to do it using a custom plugin.

3 Likes

I’m not sure what you mean by keeping the two systems independent? Let me know if I’m missing some obvious way of solving the problem I’ve laid out, please!

Otherwise, it seems my options are:

  1. When a user times out on the main site, before I log them out, call Discourse and check the last_seen value to see if the member has actually been active in the forums (just not doing anything that generates a webhook call). Pros: easy to do. Cons: will generate a lot of API calls, which is something I’m already struggling with and dealing with working around the rate limits.

  2. Create my own plugin to ping my main site every now and then, so I can update the user’s last activity time on my main site. Pros: feels more like the “right” solution (to indicate activity with a push message); somewhat elegant. Cons: not easy to implement.

  3. Change the logout time on my main site to 2 hours. Pros: easy to implement. Cons: are there any?

  4. Don’t worry about it. Users get logged out in the middle of their Discourse session and complain mightily. This is what I have now. :wink: Pros: easy to implement, lol. Cons: a very poor user experience.

Did I miss anything?

Seems like #3 would be a good answer, though I need to think through the ramifications of having a longer logout time on the main site.

I still like #1 as the best choice, but then I have to sort out how to prevent so many damn rate limit issues. I wish there was a way to globally turn off all rate limits in Discourse (and nginx, since I’m using the Discourse Docker install), period, full stop. I don’t need any of them. It’s only my main site talking to my Discourse instance. I don’t allow user API keys and I am the only one with a system API key. It’s a completely closed system and rate limits are doing nothing but (constantly) getting in my way. I guess that’s a different topic.

If you need to keep the behaviour you outlined, then yes I think those are the 4 options. But if you change the behaviour a little then it will work better with the tools available.

The unusual bit about your setup is:

You are killing the discourse session whenever the session expires on your main site. If you remove this piece, I think the setup will match typical setups.

You could still call /logout when a user explicitly logs out from your main site. Just don’t call it when the session expires naturally.

3 Likes

Can’t tell from OP but are you running a highly specialized site based around folks sharing super sensitive info, or where most users are logging in from shared public computers or something?

By far the simplest solution here seems like it would be to just not be hyper-aggressive in expiring user sessions and forcing logout. My preference as a user is always “never log me out unless I specifically click logout”. If that’s not possible could you at least make it one day or one week or something?

4 Likes

I see-- that’s a good solution; I think enough of my members use the “keep me logged in” checkbox on the login page that it would be seamless to bring them back to the main site. If their session has expired on them main site, they would be (invisibly) logged back in right at that point. Hmm.

It’s a site for a segment of the population that is very sensitive about privacy. But I see what you’re saying and I think I could just do as you (and David) suggest.

Thank you both, very much. I didn’t have a good sense of the “bigger picture” here, or how other sites handle this kind of scenario… now I do :slight_smile: and I see some possible solutions for my situation. Much appreciated!

4 Likes