Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly handle a JWT refresh?

I have an android app. It connects with a REST API developed with Jersey. My REST End points are secured with Tokens. Below is how I generate them.

Algorithm algorithm = Algorithm.HMAC256(secret);
String token = JWT.create()
    .withClaim("userName","myusername)
    .withExpiresAt(expirationDate)
    .sign(algorithm);

Below is how I validate the token

public boolean validateTokenHMAC256(String token, String secret) throws UnsupportedEncodingException, JWTVerificationException
    {       
        Algorithm algorithm = Algorithm.HMAC256(secret);


        JWTVerifier verifier = JWT.require(algorithm) 
                .build(); //Reusable verifier instance
            DecodedJWT jwt = verifier.verify(token);

            Claim usernameClaim = jwt.getClaim("username");
            String username = usernameClaim.asString();
            System.out.println(username);


        return true;
    }

In my REST API I have a filter and that filter checks every request to see whether the token is as it is. Below is the code.

@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter{

    //private static String authorizationSecret = "ZXW24xGr9Dqf9sq5Dp8ZAn5nSnuZwux2QxdvcH3wQGqYteJ5yMTw5T8DBUJPbySR";

    public AuthenticationFilter()
    {
        System.out.println("test printing");
    }

    @Override
    public void filter(ContainerRequestContext crc) throws IOException
    {
        String headerString = crc.getHeaderString("Bearer");
        System.out.println("bluh: "+headerString);
        System.out.println("test printing");

        try
        {
            boolean validateToken = validateToken(headerString, AuthKey.authorizationSecret);
            System.out.println("valid");
        }
        catch(Exception e)
        {
            System.out.println("invalid");
            crc.abortWith(
                Response.status(Response.Status.UNAUTHORIZED).build());
        }

    }

    private boolean validateToken(String strToken, String secret) throws UnsupportedEncodingException, JWTVerificationException
    {
        Token token = new Token();
        return token.validateTokenHMAC256(strToken,secret);
    }



}

The above code will be called when the user login to the application. However the token will be expired in 60 minutes. I know that after the token is expired either I have to take the user back to sign in screen or refresh the token. I went through the advices in here and here

But I do not understand the following.

  1. How can I figure out whether the token has to be renewed? I thought I should do that after it is expired, but seems that is not the case. If I ask it to refresh in now<exp it will refresh in every request.

  2. How can I assign and send this token back to the user? Currently when the user login on, he will get the token and he will save it in a variable. For the refreshed token to work, do I have to call the login method again (So the token will be sent to the user) or JWT it self will handle the case?

  3. How do I actually refersh using java-jwt ?

like image 722
PeakGen Avatar asked Mar 29 '17 10:03

PeakGen


People also ask

How do you handle a refresh JWT token?

We'll first create an express app and then implement two routes login & refresh. The login route will get a post request, then it will check the credentials if they match it'll send a refresh token and access token in response.

How do you handle refresh token?

To use the refresh token, make a POST request to the service's token endpoint with grant_type=refresh_token , and include the refresh token as well as the client credentials if required.

How long should a JWT refresh token last?

Authentication is implemented through JWT access tokens along with refresh tokens. The API returns a short-lived token (JWT), which expires in 15 minutes, and in HTTP cookies, the refresh token expires in 7 days.

Where should I store my refresh token?

The authorization server can contain this risk by detecting refresh token reuse using refresh token rotation. If your application uses refresh token rotation, it can now store it in local storage or browser memory.

What is the difference between JWT and refresh JWT?

JWT represents a short-lived access token. Short-lived here means usually anything between 5 minutes to 24 hours or days depending on your application. Refresh tokens are long-lived and represent a mechanism for silent authentication to obtain a new access token without any user action.

Where are refresh tokens stored in JWT?

Refresh token usually holds just an opaque identifier and it is stored either as an httpOnly, secure cookie or within web storage (either of which enables your website to work in multiple open tabs in case that you store your access token in memory as recommended earlier). How to sign out users with JWT access tokens?

How long do JWT access tokens last?

Authentication is implemented through JWT access tokens along with refresh tokens. The API returns a short-lived token (JWT), which expires in 15 minutes, and in HTTP cookies, the refresh token expires in 7 days.

How do I enable silent authentication in JWT?

Load user data from your database based on the user ID stored in the JWT subject. When the access token expires, silently authenticate the user again by using the refresh token. Perform the silent authentication by using a refresh token to provide both a new access token and a new refresh token.


1 Answers

  1. How can I figure out whether the token has to be renewed? I thought I should do that after it is expired, but seems that is not the case. If I ask it to refresh in now

You need to refresh the token before it is expired. Decide your policy:

  • issue a fresh token in every request

  • issue a fresh token when the current one is close to expire. e.g. 10 min

  • let client app request a new token when it needs it using a "refresh service" of your api. For example


@GET
@Path("/jwt/refresh")
@Produces(MediaType.TEXT_HTML)
public String refresh(){
    //Build a returns a fresh JWT to client 
}
  1. How can I assign and send this token back to the user?

If you issue a fresh token during a request, you can return it in a special header that client will read during processing of the response. If you publish a "refresh" service as described above, then the client will call it independently when the current JWT is close to expire

Redirect to login method is not a good alternative because you will lose the current request

  1. How do I actually refresh using java-jwt

Just issue a new token

like image 64
pedrofb Avatar answered Nov 09 '22 22:11

pedrofb