如何正确处理JWT刷新?

时间:2017-03-29 10:09:44

标签: java rest jersey jwt auth0

我有一个Android应用程序。它与使用REST API开发的Jersey相关联。我的REST端点由令牌保护。以下是我如何生成它们。

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

以下是我验证令牌的方法

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;
    }

在我的REST API中,我有一个过滤器,该过滤器检查每个请求以查看令牌是否原样。以下是代码。

@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);
    }



}

当用户登录应用程序时,将调用上述代码。但是令牌将在60分钟后过期。我知道在令牌过期后,我必须让用户返回登录屏幕或刷新令牌。我查看了herehere

中的建议

但我不理解以下内容。

  1. 如何确定令牌是否必须续订?我认为我应该在它过期后这样做,但似乎并非如此。如果我要求它在now<exp中刷新,它将在每个请求中刷新。

  2. 如何将此令牌分配并发送回用户?目前,当用户登录时,他将获得令牌并将其保存在变量中。为了使刷新的令牌工作,我是否必须再次调用login方法(因此令牌将被发送给用户)或JWT它自己将处理案例?

  3. 我如何使用java-jwt实际引用?

1 个答案:

答案 0 :(得分:5)

  
      
  1. 如何确定令牌是否必须续订?我认为我应该在它过期后这样做,但似乎并非如此。如果我现在要求它刷新   

您需要在令牌过期之前刷新令牌。确定您的政策:

  • 在每个请求中发出一个新令牌

  • 在当前的令牌即将到期时发出新令牌。例如10分钟

  • 让客户端应用在需要时使用&#34;刷新服务&#34;你的api。例如

@GET
@Path("/jwt/refresh")
@Produces(MediaType.TEXT_HTML)
public String refresh(){
    //Build a returns a fresh JWT to client 
}
  
      
  1. 如何将此令牌分配并发送回用户?
  2.   

如果在请求期间发出新令牌,则可以将其返回到客户端在处理响应期间将读取的特殊标头中。如果您发布了&#34;刷新&#34;如上所述的服务,然后客户端将在当前JWT接近到期时独立调用

重定向到登录方法不是一个好的选择,因为您将丢失当前请求

  
      
  1. 如何使用java-jwt实际刷新
  2.   

只需发出新令牌