Best way to use access tokens for authentication and authorization

338 views Asked by At

What is the best approach to use personal access tokens for authentication and authorization of a mobile app?

What I do is on login I generate a token valid for 30 mins. On each request, all the tokens are deleted and a new one is issued.

My logic is that if someone steals the token, he has to use it in 30 mins, otherwise is useless. If he manages to do it, the next time the user logs in, the stolen token or the tokens created with the stolen one are deleted, only the user will have a valid token.

Why it's this worse than the normal approach where on login you get a token and a refresh token, when the token expires you use the refresh token to get a new valid token. If someone steals your tokens, he can use the refresh token to generate new tokens forever or until the refresh token expires.

1

There are 1 answers

2
akdombrowski On BEST ANSWER

Yes, you're spot on. Keeping the lifetimes of things like tokens as short as possible is best security practice. Not just for tokens, too. That's why we do things like rotate keys every 30 days or however long is manageable. If you have a token with a lifetime for a full year, you're opening the risk to a malicious actor having access for a full year.

However, the reason why you see a lot of people getting an access token along with a refresh token right away, and why refresh tokens were even added to the OAuth 2.0 spec, is that the user experience can suffer. A user having to enter their username and password every 30min can be a pain and dissuade them from using your app. Or, perhaps worse, users will look for a workaround which ends up being less secure and defeats the purpose of the security measures you've implemented.

The refresh token is a sort of compromise.

It's basically saying, if you don't want to keep making your users login to get a new access token, then, fine, use this thing called a refresh token. So, you get the benefit of the short-lived access token AND you can also get a new 30min token without having to make the user login again.

But, I'm sure you're asking, what if the bad actor gets a hold of the refresh token?

Well, that's why it's a compromise. It's not as good of security as just issuing a 30min token every time the user authenticates. But, it's better than giving that access token a really long lifetime.

Why is it better?

In order to use the refresh token to get a new access token, it has to be sent to the authorization server. Potentially, the authorization server can perform other checks to see if the request is coming from a bad actor or not. They can check the IP of the client sending the request or look at the location vs. previous locations or look at the device's fingerprint to see if it's a device that this user has never used before. Then you can send the user a code to their registered email to verify it's actually them or lots of other things. They aren't foolproof and the authorization server needs to actually implement them but it's a step that the long-lived access token doesn't have.

There are other measures you can take as well. You need to be using PKCE. And DPOP was just turned into an RFC Sep 2023. And, have a look at the best current security practices they update quite frequently with the latest in Oct 2023. OWASP can be helpful as well.

Yes, there's a lot. That's why, unfortunately, security is hard.