DEV Community

endan
endan

Posted on

What is the usual flow in authenticating a Client Application with a Token based REST API?

Hello everyone. I'm really stuck right now and can't progress. I am having a hard time concieving the proper flow in authenticating a client app with a token based api authentication.

Here's what I have so far:

Client app provides a login screen ->
Client app sends a /POST request to the /api/auth route ->
API checks if the user exists, returns Access token and Refresh token ->
Client app saves the access token as http-only cookie or localStorage ->
... stuck (Don't know what to do with the Refresh Token)

My train of thought gets stuck at this part.

If I have the users collection on the API side, then how should I store my Refresh Token? I know it's recommended to be stored at a database or something secure.

But won't that make me have duplicate users table, something like that?

I don't really know how to proceed, and I think I haven't read an excellent source material about this flow before.

If you have a tutorial to help me, or any recommendations, I'll gladly accept. I'm stuck. 😢

Thanks. Hope dev.to can help me.

Latest comments (19)

Collapse
 
nikosdev profile image
Nikos Kanakis

Hi endan, i am in the same situation. I dont know how to refresh jwt token and i have the same question with @nick_karnik about refresh token security. Did you find any solution?

Collapse
 
jjjjcccjjf profile image
endan

Hey there Nikos. Unfortunately, I have not found any solution to this. If you are stuck in the development process, I suggest to do your core features first and do this last. (contrary to Ben's comment in another post)

Collapse
 
docoprusta profile image
Soma Györe • Edited

Hi!

I have a bit of experience of flask with flask-jwt-extended extension. With this library it is not required to save refresh tokens only if you want to revoke/blacklist them. There is a @jwt_refresh_token_required decorator that can validate the sent refresh token.

If you use some other programming langue and/or framework you can implement this feature. The only thing that you should do to put "type": "refresh" to the payload and check the token contains it or not if refresh token is required.

If blacklisting and/or revoke token feature is required for you than you should store the tokens in a database (or in a variable but it is not recommended)

More info:

flask-jwt-extended.readthedocs.io/...
flask-jwt-extended.readthedocs.io/...

Collapse
 
lims profile image
Lucas • Edited

Hi!

You should use the refresh token to get a new access token when it gets expired, so you'll need a column in the table where you store the user info (like username and password) to put the refresh token there.
The interesting thing about refresh tokens is that you don't have to request the users for their credentials since you just have to check the refresh token in your DB table with the one that is sent from the app.
In resume what do you need:

  • Add a column in the user info table to store the refresh token there.
  • Add a endpoint in the api to obtain a new access token from an existing refresh token.
  • You should find a way to store the refresh token in the client-side so you can send it when the access token gets expired. Keep in mind that however, the refresh token should have an expiration time too, and it should be much greater than the expiration time of the access token, and when the refresh token expires it will be time to ask the user for his credentials.
  • The flow of the app would be like this:
    1. The user authenticates whit his credentials and gets Access + Refresh tokens
    2. The user uses the app accesing resources with the access token
    3. After a certain amount of time the access token gets expired, when this happens the app requests the api for a new access token using the refresh token.
    4. The following calls to the api uses the new access token.

I'm really sorry for my english, and if there is an error on my explanation please let me know!

Good Luck!

Collapse
 
jjjjcccjjf profile image
endan

Thank you for your effort to explain in great detail! I completely understand your English. ☺

I have a question. How do you store the refresh token on the client-side? Would that mean there will be some kind of 2nd user database aside from the user database in the api-side?

Collapse
 
lims profile image
Lucas

On the client-side you can store the refresh along with the access token in local storage, and in the api-side you just have to add a new column in the user info table (I suppose you have a table where do you have columns like 'username', 'password',...) I don't understand why you think that you have to create another database

Thread Thread
 
jjjjcccjjf profile image
endan

But isn't storing Refresh Tokens on localStorage a bad practice because it can be tampered?

Thread Thread
 
skyrpex profile image
Cristian Pallarés

IMO you should NOT store those credentials in local storage. Refresh tokens are supposed to only be seen by servers, aren't they?

Take a look at Laravel Passport approach: uses traditional cookies to store an access token and a CSRF token.

Thread Thread
 
lims profile image
Lucas

The refresh token by itself does not provide any information about the user, (the access token yes), so I don't really see the problem in storing it in local storage. However, I understand your concerns.

Thread Thread
 
skyrpex profile image
Cristian Pallarés

The issue is about letting the JS have access to any kind of credentials. Traditional session cookies are usually http only for that matter. The same applies to access tokens or refresh tokens.

It's just about avoiding attack vectors.

Collapse
 
theoutlander profile image
Nick Karnik

Just curious, why are you using refresh tokens if you are not sure what to do with it?

Collapse
 
jjjjcccjjf profile image
endan

I know how refresh tokens work and their purpose; it adds another layer of security to the API. But what I do not know, and wish to know, is how to implement them the right way. You see, I don't have formal education about this and I am just trying to teach myself. 😶

Collapse
 
theoutlander profile image
Nick Karnik

Can you explain more about your use-case? Is this a web app or a mobile app? What sort of security is a refresh token providing? I'm trying to understand the intent of using a refresh token here.

Thread Thread
 
jjjjcccjjf profile image
endan

It will be a web app. I want to utilize the concept of refresh tokens because keeping a permanent access token looks bad for me. If they token gets stolen, then a user can be spoofed. If I do put an expiry though, they would login every time the token expires. Wouldn't that be a hassle? That's why I want to use refresh tokens.

Thread Thread
 
theoutlander profile image
Nick Karnik

Fair enough. Which supplementary information are you planning on submitting with the refresh token to get an access token?

Thread Thread
 
jjjjcccjjf profile image
endan

I'm not sure.. I think only the refresh token alone?

Thread Thread
 
theoutlander profile image
Nick Karnik

I see. How does it make it secure in that case? Anyone who gets a hold of the refresh token can still request an access token right? I think the idea of a secure refresh token is that anyone who discovers it cannot do anything with it because additional pieces of information are required in order to request an access token.

Thread Thread
 
ayazhussein profile image
Ayaz Hussein

Hey, What other information can be used to differentiate between stolen refresh token and a valid refresh token?

Thread Thread
 
bwighthunter profile image
Blake Wight

This reply is a bit late, but perhaps useful to a future passer by. What you could do is have the front end pass in some information about where they are located and/or their device/browser and then tie refresh tokens to each device/browser. This could allow the user to revoke refresh tokens per location/device. If a request provides a token from a new location (for that token) revoke it and require another login from that device. Still spoofable, but it adds another layer.