Using Refesh Token in Token-based Authentication is secured?
Asked Answered
R

2

6

I am building a token based authentication (Node.js using passport/JWT with an angular client).

After the user enter his credentials he gets an access token, which he sends in every request inside the header (header: bearer TOKEN).

I don't want to prompt a login request everytime his access token expires (about everyday I guess), I've heard about the Refresh Tokens. The refresh token never expires (or rarely expires) and able to renew tokens indefinitely.When the access token is about to expire, the client can send a renew request to get a new access token by sending his refresh token.

I don't understand few things, I might be missing something:

  1. How a long-living/never expiring refresh tokens don't ruin the security of having short-living access tokens.

  2. Cookies can be stole and be used until they expire. Tokens are short living so they more secured, but if I provide a long-living refresh token I lose the advantage of using tokens.

NOTE: I am aware that the refresh tokens are sent at the initial login, so cann't be spoofed in every request, but if they are spoofed at the initial request they are vulnerable.

Redmon answered 8/12, 2014 at 13:27 Comment(0)
S
4

The refresh token is presented on a different path than the access token: the access token is only ever presented to the Resource Server, the refresh token is only ever presented to the Authorization Server. The access token can be self-contained so that it does not need costly calls to the Authorization Server to check its validity, but to mitigate loss and to increase accuracy (it cannot be revoked in case something goes wrong) it is short-lived. The refresh token is long lived and gets validated on each call to the Authorization Server and as such it can be revoked. The combination of the two makes the system secure.

Stochmal answered 8/12, 2014 at 13:50 Comment(5)
I think I am starting to understand. so the access token is passed between the client and the server, and the refresh token is passed between the server and the authorization server. but what if my server has both resource and authorization logic and not relaying on different authorization server? then the refresh token will be unnecessary, and when the clients provide an outdated access token or an access token which expires soon I will simply generate a new token and pass it to him? doesnt it mean that if a hacker has the access token he can exploit it forever just renewing it over and over?Redmon
a new access token should only be granted to clients based on some sort of "authorization grant" as OAuth 2.0 calls it, and must not just be based on the possession of an old access token, otherwise indeed the lifetime of the token has no meaningStochmal
Can you tell me what authorization grant I can use without requiring the user to enter his credentials again? (in order to avoid prompting login every time the access token expires)Redmon
that's the refresh token grant... if a hacker gets hold of the refresh token it should be revoked and the user will be prompted for authentication again; two sides of the same coin: either you rely on an existing token or you prompt the user for authentication; if your client is insecure there's no remedy anyhowStochmal
Hi Hanz, could u pls help me in this #28760090Transparent
A
0

I use the following approach:

Tables/indexes:

  1. User table (just has the user ids and all the user related meta-data)
  2. JWT table (three fields : user_id, access_token, refresh_token)

Authentication Flow

1.When a previously unauthenticated user signs in, issue a JWT which contains an access token, and a refresh token. Update the refresh token in the JWT table, together with the user_id, and the access token.

2.Make sure that the JWT has an expiration time that is something small/comfortable for your users. Usually less than an hour.

4.When a client makes a request with a JWT

a. Check expiry of the access token. If the token has not expired -> continue without hitting any db tables.

b. If the access token has expired, lookup the user_id in the JWT table, and check if the refresh token and access tokens match, whatever the client has provided,

If yes, issue a new JWT with the response and update the new refresh token,access token into the JWT table.

if no, return 401. The client is forced to ask the user to then sign in.

END.

To summarize,

1.DB calls are required only to check if the refresh token is valid.

2.This system allows for a user to sign in from any number of devices, with any number of JWT's

3.All JWT's related to a user can be invalidated, by wiping the refresh tokens related to that user from the JWT table, this can be done, for eg: when a user changes his/her password. This, in effect, narrows down the window of compromise to the expiration time of the access token/JWT.

I believe this is the intention behind JWT's. The percentage of DB calls/user depends on your expiration time, the duration a user is usually on your website, etc.

Anorthic answered 16/8, 2020 at 11:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.