Token realizes login, token expiration resolution and data analysis

What are tokens?

        We can understand token as a token, the main function is to protect the security of our system, such as our login, we can use token to verify user data, so why not use traditional session? The main thing is that the session is generated for us by the front-end page. When a certain window is closed or the session changes, it will stop when the service is requested. The initiative of the session lies with the front-end, and the initiative of the token lies with the server.

So how do we achieve it? Check out the code below!

<!--Import the following dependencies--> 
<dependency> 
    <groupId>com.auth0</groupId> 
    <artifactId>java-jwt</artifactId> 
    <version>3.3.0</version> 
</dependency>

generate token

    //设置过期时间(毫秒为单位)
    private static final long EXPIRE_DATE=1*60*1000;
    //token秘钥(可以自定义一个随机字符串就行,避免中文)
    private static final String TOKEN_SECRET = "ZCEQIUBFKSJBFJH2020BQWE";

    /**
     * 
     * @param username  传入用户名
     * @param password  传入密码
     * @return
     */
    @GetMapping("/getToken")
    public String getToken(String username, String password) {
        String token = "";
        try {
            //过期时间
            Date date = new Date(System.currentTimeMillis() + EXPIRE_DATE);
            //秘钥及加密算法
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            //设置头部信息
            Map<String, Object> header = new HashMap<>();
            header.put("typ", "JWT");
            header.put("alg", "HS256");
            //携带username,password和用户ID信息,生成签名,按照需求而定
            token = JWT.create()
                    .withHeader(header)
                    .withClaim("username", username).withClaim("userId", 用户id)
                    .withClaim("password", password).withExpiresAt(date)
                    .sign(algorithm);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return token;
    }

Check whether the token has expired

  /**
     * 校验Token是否过期
     * @param token
     * @return
     */
    public static boolean verifyToken(String token){
        try {
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm).build();
            verifier.verify(token);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return  false;
        }
    }

Parsing token information

   /**
     * 解析Token
     * @param key     需要解析的key字符串(username、userId等等,就是携带数据生成token的Key)
     * @param token   传入token
     * @return
     */
    public static String getUsername(String token,String key){
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim(key).asString();
        }catch (JWTDecodeException e){
            e.printStackTrace();
        }
        return null;
    }

Many people may directly use the above code to implement the login interface, so have you ever thought about a problem? The expiration time of the token is set above. When the user is using our software, suddenly the token expires and directly reports a 401. At this time, the user must be confused. This problem occurs in many software, because of laziness Yes, we don't often find out that it's because their tokens have a longer expiration time. I provide you with a solution below.

1. The background can cache the token when generating the token and returning it to the front-end. For example, if the expiration time of our token is 30 minutes, then we can set the validity period of the cache to 10 minutes. The front-end refreshes our cache every time it requests, if the front-end 10 minutes If there is no request, our token will automatically expire. What if our cached token has not expired but the actual token has expired? At this time, we can directly generate a new token and return it to the front end.

2. When generating tokens, generate two tokens and return them to the front end (if two tokens A and B are generated), the Token of A is returned to the front end for data interaction, and the Token of B is used to refresh the Token of A. At this time, we can Set B to a longer expiration time. When the background finds that A has expired, return 401 to the front-end. The front-end is using B to exchange for a new token. When we receive the token exchange notification in the background, we will parse the original data in A and reuse the data to generate A new token is returned to the frontend.

Warm reminder: When we generate tokens, we need to pay attention to prevent others from analyzing the data in it. It is best to encrypt the data in the token. For example, some students use account passwords to generate tokens. This method should pay special attention.

Guess you like

Origin blog.csdn.net/qq_38935605/article/details/127442471