如何正确处理 JWT 刷新?

Posted

技术标签:

【中文标题】如何正确处理 JWT 刷新?【英文标题】:How to properly handle a JWT refresh? 【发布时间】:2017-08-22 18:20:50 【问题描述】:

我有一个安卓应用。它与使用Jersey 开发的REST API 连接。我的 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 分钟后过期。我知道令牌过期后,我必须让用户返回登录屏幕或刷新令牌。我查看了here 和here 中的建议

但我不明白以下内容。

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

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

    如何使用java-jwt 实际引用?

【问题讨论】:

【参考方案1】:
    如何判断令牌是否需要更新?我以为我应该在过期后这样做,但似乎并非如此。如果我现在要求它刷新

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

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

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

让客户端应用在需要时使用您的 api 的“刷新服务”请求新令牌。例如


@GET
@Path("/jwt/refresh")
@Produces(MediaType.TEXT_html)
public String refresh()
    //Build a returns a fresh JWT to client 

    如何分配此令牌并将其发回给用户?

如果您在请求期间发出新的令牌,您可以在客户端将在处理响应期间读取的特殊标头中返回它。如果你发布了一个如上所述的“刷新”服务,那么当当前的 JWT 接近过期时,客户端会独立调用它

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

    如何使用 java-jwt 实际刷新

只需发行一个新令牌

【讨论】:

谢谢。 If you stablish a refresh service, then the client will call it independently. - 不清楚,请解释 谢谢。所以基本上在 refresh() 方法中我要做的是; 1.检查token是否过期。 2. 如果没有过期,请调用我的问题中的第一组代码,它能够生成令牌。我对么? If you publish a "refresh" service as described above, then the client will call it independently when the current JWT is close to expire - 这意味着客户应该跟踪他的 JWT 是否接近到期,对吗?我的客户端是安卓应用,所以安卓应用应该检查token是否过期,不是吗? 是的,就是这样。要检查过期,android 应用可以检查令牌负载中的exp 声明

以上是关于如何正确处理 JWT 刷新?的主要内容,如果未能解决你的问题,请参考以下文章

使用 express 执行 jwt 刷新令牌的正确方法

如何正确处理标头中的 JWT

如何使用 jwt 在 React 中正确存储当前用户信息

如何使用 Yesod 正确处理 JWT 的到期日期?

我是不是正确理解用于身份验证的访问和刷新令牌技术?

如何使用 Spotify SDK 和 Swift 3 正确处理令牌刷新。错误代码 = 3840