如何正确处理 JWT 刷新? [英] How to properly handle a JWT refresh?

查看:36
本文介绍了如何正确处理 JWT 刷新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个安卓应用.它与使用 Jersey 开发的 REST API 连接.我的 REST 端点由令牌保护.下面是我如何生成它们.

Algorithm algorithm = Algorithm.HMAC256(secret);字符串令牌 = JWT.create().withClaim("用户名","我的用户名).withExpiresAt(expirationDate).sign(算法);

以下是我验证令牌的方法

public boolean validateTokenHMAC256(String token, String secret) 抛出 UnsupportedEncodingException, JWTVerificationException{算法算法 = Algorithm.HMAC256(secret);JWTVerifier verifier = JWT.require(算法).建造();//可重用的验证器实例DecodedJWT jwt = verifier.verify(token);声明 usernameClaim = jwt.getClaim("username");String username = usernameClaim.asString();System.out.println(用户名);返回真;}

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

@Secured@提供者@Priority(Priorities.AUTHENTICATION)公共类 AuthenticationFilter 实现了 ContainerRequestFilter{//私有静态字符串authorizationSecret = "ZXW24xGr9Dqf9sq5Dp8ZAn5nSnuZwux2QxdvcH3wQGqYteJ5yMTw5T8DBUJPbySR";公共认证过滤器(){System.out.println("测试打印");}@覆盖public void filter(ContainerRequestContext crc) 抛出 IOException{String headerString = crc.getHeaderString("Bearer");System.out.println("蓝色:"+headerString);System.out.println("测试打印");尝试{boolean validateToken = validateToken(headerString, AuthKey.authorizationSecret);System.out.println("有效");}捕获(例外 e){System.out.println("无效");crc.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());}}private boolean validateToken(String strToken, String secret) 抛出 UnsupportedEncodingException, JWTVerificationException{令牌令牌=新令牌();return token.validateTokenHMAC256(strToken,secret);}}

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

但我不明白以下内容.

  1. 如何判断令牌是否需要续订?我以为我应该在它过期后这样做,但似乎并非如此.如果我要求它在 now 中刷新,它将在每个请求中刷新.

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

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

解决方案

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

您需要在令牌过期前刷新令牌.决定您的政策:

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

  • 在当前令牌即将到期时发出一个新令牌.例如10 分钟

  • 让客户端应用程序在需要时使用 API 的刷新服务"请求新令牌.例如

<小时>

@GET@Path("/jwt/刷新")@Produces(MediaType.TEXT_HTML)公共字符串刷新(){//构建一个返回一个新的JWT给客户端}

<块引用>

  1. 如何分配此令牌并将其发送回用户?

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

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

<块引用>

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

只需发行一个新的令牌

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 ?

解决方案

  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

这篇关于如何正确处理 JWT 刷新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆