Java Spring JWT with refresh token workflow questions

16,091

What is the best way to distinguish the two tokens.

Refresh token does not have to be a JWT at all. I prefer to simply generate a random alphanumeric string. Refresh token does not carry any additional information. It requires a lookup to database to confirm validity of refresh token. You distinguish them by where they appear in your request. Authorization token (access token) should appear in a header of your choice.

What should be the error in step 3 (instead of unauthorized) to distinguish it from a request without a valid token

Sending 401 Unauthorized is exactly the way to do it. 401 tells the client, that he cannot access the resource now, but he can take actions so that he can access the resource again (login/refresh token). 403 on the other side would tell the client, that the resource does not belong to him and he will have to ask for permissions, e.g. by contacting an admin

/token/refresh doesn't ask for authentication currently. Should it?

No, there is no need for authentication.

Should the /token/refresh endpoint be a POST with header, POST with parameters or a GET with header.

Generally a GET endpoint should be read only and not mutate any resources. POST and PUT endpoints are intended for mutations. In this, I'd use a POST with parameters and a dedicated URL, e.g. /token/refresh

Share:
16,091
D.Tomov
Author by

D.Tomov

Java Engineer

Updated on July 18, 2022

Comments

  • D.Tomov
    D.Tomov almost 2 years

    I have some questions regarding an API JWT refresh token workflow using Java Spring.

    I have this so far:

    1. User logs in to /users/login - if successful a response with 2 headers is returned Authorization and Refresh. Which contain 2 tokens - one with short 30 mins expiration and one with longer 4 hours expiration.
    2. He can then access all other endpoints using the Authorization header.
    3. If at some point accessing an endpoint his token is expired he receives an error (UNAUTHORIZED).
    4. And has to do a request to /token/refresh with the refresh token he was given.

    Questions:

    • I have set it up so authorization token has a claim: type=auth and the refresh token has a claim: type=refresh. What is the best way to distinguish the two tokens.
    • What should be the error in step 3 (instead of unauthorized) to distinguish it from a request without a valid token
    • /token/refresh doesn't ask for authentication currently. Should it?
    • Should the /token/refresh endpoint be a POST with header, POST with parameters or a GET with header.
  • D.Tomov
    D.Tomov over 5 years
    Thank you very much. If I don't want to store the refresh tokens in a database is there a way to do it?
  • ygor
    ygor over 5 years
    Yes, of course, you can represent refresh tokens as JWT. But there is a catch to it. Expiration date of a JWT is "written in stone". It will be invalidated after 4 hours, period. However, there are plenty of scenarios, when you want to expire refresh token soon. Example one: Explicit logout -> user presses "logout" button. Example two: you want to ban the account immediately and not allow user to use the refresh token anymore. Example three: the request for the refresh looks suspicious -> it comes from a different user agent, different country ...
  • ygor
    ygor over 5 years
    You can check a full example at github.com/ygor-sk/stackoverflow/tree/master/…
  • D.Tomov
    D.Tomov over 5 years
    Thank you very much
  • DvixExtract
    DvixExtract over 4 years
    @ygor great answer thanks for the example however in the example passing a jwt token to any of the endpoint that require a token returns a 401, what could be reason.