Is there an endpoint to check if a user is logged in

I need a URL that will return 200 for a logged in user and 401 or 403 if the user is not logged in.

If require_login is checked, every page does a 301 to the login page.

1 Like

Is this a user request, i.e. using the current users session?

Or…

Is this an admin API request using an admin API key?

Yeah. It’s me not understanding the question I’m asking.

I’m trying to do an auth_request in NGINX to tell whether the request is coming from a user that’s logged in by querying an URL to see whether it gets a 200 response or not.

It’s occurring to me that doing that is not quite as simple as I’d hoped.

You could try /session/current.json

It will return 200 if authenticated and 404 if not.

Generally .json / API requests don’t redirect.

https://github.com/discourse/discourse/blob/master/app/controllers/application_controller.rb#L575-L589

3 Likes

That seems promising. I’ll keep poking at it.

Many thanks!

Is there an easy way to do this from a different subdomain?

Example, the forum is at forum.example.com and the request is coming from example.com (either from the frontend or backend code).

Sure. You can make an API call from anywhere.

But this specific call needs to be done from the frontend, since it will use the session cookies sent by the browser to the forum.

1 Like

The Discourse session cookie appears to be just for the subdomain, so would the cookie be accessible from the top-level domain? I see _forum_session on the Discourse subdomain but it doesn’t appear when visiting the TLD.

If the cookie were available on the top-level domain, I was thinking that it would also be passed to the backend, so the backend could forward it to Discourse, but I’m not sure.

Maybe it requires using Discourse as an SSO provider? If it isn’t known whether the user is logged in, then we could redirect through the SSO process to check. I’m currently setting it up on a test server to see if it would work.

Edit: my end goal is to generate a JWT with the user data from Discourse (only if logged in to Discourse) and pass it to Firebase. There is a Discourse server on the subdomain, an extra backend server that can perform additional logic, and an SPA that connects to Firebase if given a JWT.

If you want anything fancy like this you would need to implement your own CurrentUserProvider

3 Likes

Thanks, I just looked it up and found this other thread, so I’ll ask some more questions about it over there.

Edit: it looks like we can do what we need with Discourse as an SSO provider.

2 Likes

If you can do it with SSO I highly recommend you go that path vs a provider

3 Likes

Thanks, it looks like we can check if a user is logged in and then redirect through Discourse’s SSO route if not logged in. It seems to work well on my laptop. The user logout webhook from Discourse can then log them out of the other app.

2 Likes

Can you please explain a bit on how we can check if a user is logged in to Discourse from another subdomain? I am trying to implement an auth middleware in my route handlers (on server) to check if the user’s log in to Discourse as a SSO is still valid.

I’m trying to implement almost the same thing for a web app but can’t figure out how to check if the user is still logged in.(Preferably logged in from the same browser currently used to send the request to server)
Thank you!

1 Like

My code for it isn’t live yet, but if the user is redirected through another server (with Discourse as an SSO provider), then a session will exist in that external server. I created a route there, something like /auth/is-authenticated that returns the user’s status. It’s mainly just there to remove the “log in” buttons when they are already logged in. When the user logs out of Discourse, I think a webhook logs them out of the other server. I haven’t checked the code in a while, but I think that’s how I set it up.

How can an external server route check if the user’s browser is still logged in to Discourse? I don’t think another domain can even access Discourse’s cookies set after login.

My goal is to logout the user from the external (not Discourse) server if the user logged out of Discourse using the current active browser only. (Is it even possible?)

Thanks for the reply.

When the user is on the external app, they click a log-in button and get routed through Discourse’s SSO provider flow, and back to the external app. That external app can store a session with the user’s data. When the user logs out of Discourse, the webhook can delete the external app’s session. I’m not certain, but I think the webhook header is X-Discourse-Event: user_logged_out.

Edit: logging out from the external site is done with the Discourse API.

Instead of asking Discourse whether a user is logged in, you can ask the external app. In my case it’s just for things like removing the log-in button in the external site.

I can double check my code later. I haven’t looked at it in a while, but I think it did something like that.

1 Like

Thanks for the reply! Really appreciate it.

Yes it is clear to me now. Only catch here in logging out with the API is that the User will be logged out of all sessions (on all devices - as the API cannot discern between the current browser’s session and other logged in browsers).

1 Like