What’s in a Token? – An OpenID Connect Primer, Part 3 of 3

Micah

Thank you!

Micah

Thanks so much!

Insta

Such a fantastic series that clearly explains the OIDC flow even for beginners. Great work!

Jamal

Great series Micha.
Question for you. If I use Okta to log users into to my SPA, which token should be used to determine access to certain SPA routes and page features the user can access (based on the user’s Groups)? The ID, or Access token? The SPA also makes REST API calls to an in-house REST API made speficially for serving the SPA. Should a different access token be requested for this REST API, or can I forward on the ID and/or Access token?

Matt Raible

I’d recommend putting the user’s group information in a “groups” claim in the ID token. You should be able to add claims by going to API > Authorization Servers > default. Your SPA should pass the access token to the server. If the server needs additional user information, it can use the access token to call the /userinfo endpoint and get it.

PJ

Great Article !! really helped clearing a lot of confusion around OIDC.

A general question regarding storage of access token. I have this scenario -
1. User wants to access some resource at server using some js app.
2. Server sees that there is no access token, so it redirects user to authorize end point with response_type code.
3. User logs in, server gets the access token from authorization server using information in callback
4. Now, I would like this same access token to be sent by browser until it expires

So what’s the best way to store this access token, set it in a cookie with expiration equal to expiration time of access token ? Is it safe to do this ?

Micah

The safest way to manage tokens is to NEVER have them hit the browser. This may not always be feasible. BUT, let’s say you have some node.js middleware as part of your SPA app architecture. It’s much safer to leverage the session management between your spa app and node.js than to have your SPA save an access token. Now, if your SPA need something from a resource server, it makes an api call to your node.js app. The node.js app (which has the access token) makes the call to the resource server and just returns the results to the SPA.

If you MUST have the token in the browser, the next best thing is to store it as httponly cookies. This makes it so that javascript cannot “see” the access token. You DO have to deal with domain names and cookies, so you’d want to make sure that your authorization server has the same root domain as your resource server. Like: login.afitnerd.com and api.afitnerd.com. This will ensure that when your SPA makes an API call, the access token is automatically included.

Since it’s the authorization server that sets the expiration of cookies in the response, you may not have a lot of control over the expiration. But, ideally, the cookie would expire around the same time as the access token. From a security perspective, it’s not a concern, because the resource server will just reject an expired access token.

PJ

Thanks for the feedback. As I understand main concern with storing token in cookies at browser side is someone can hijack it and imitate the user by sending this token. But as far as I know sessions are also based on cookies, so if someone can hijack the session cookie wouldn’t they be able to imitate the user ?

Rajesh Singh

Really good article! I might be asking a stupid question so please excuse me. If I have two RPs and all the calls are initiated by RP1 running on sub1.domain.com how the flow will be look like from RP2 running on sub2.domain.com? Let’s say we have restriction on sharing cookie via parent domain (*.domain.com)

Micah, you’re amazing! What fantastic articles. You helped me resolve several tricky OIDC challenges for an Okta multi-tenant OIN app which uses the Microsoft Asp.Net Core authentication libraries. Thank you!