JWT + interceptor is used in SpringBoot to realize login authentication

Keywords: Java Redis Spring Boot

The old method has disadvantages

The previous strategy was the idea of UUID + redis + interceptor.

After verifying that the roomid and password match, the server uses UUID to generate a string as a token, then writes a token (roomid) to the Redis service, sets the expiration time to 20 minutes, and returns the token to the client through a response. Therefore, the client can use the token generated by this UUID to access.

For requests that need to carry tokens, an interceptor is arranged to check these requests and check whether the token and roomid carried in the request match the existing mapping in Redis. If they match, it indicates that they have been authorized and can be released. If they do not match, the request is rejected.

The disadvantages are:

  • Redis needs to be used to save many key value pairs on the server side, which takes up a certain memory space.
  • The value obtained by the client is a simple value. When there are too many users, the number of UUID s becomes too large, which will increase the probability of being guessed.

JWT

Among the three parts of the token, the first part is the header, the second part is the load, the third part is the signature, and the first and second parts are base64 encryption, which can not store sensitive information.
If the client modifies the expiration time privately, the verification phase of the token can detect it. (the expiration time is encrypted with a key)
If you modify the client roomid, does that mean you can use someone else's token? The token generation process takes the load into account, and the load can be detected to be modified during verification.
Using JWT is to trade time for space, saving space on the server side.

Method of using JWT (JSON Web Token)

Add dependencies to maven and introduce Java JWT projects.

<dependency>
        <groupId>com.auth0</groupId>
        <artifactId>java-jwt</artifactId>
        <version>3.18.2</version>
</dependency>

The server has a key that cannot be published.

After the server side verifies the roomid and password, the token signature algorithm uses the key to generate a signature according to the content of the payload. The expiration time of the token can be configured (1 hour is configured in this project). The generation of the token is equivalent to the server's authorization to the person who passes the verification, authorizing him to travel without password for 1 hour. Finally, a token is obtained and returned to the "generate method" of the client through the response. The client can use this token to make requests.

For requests that need to carry a token, an interceptor is arranged to check. The "validate method" uses the token verification algorithm to check whether the signature of the token carried by the request is valid (expired or the roomid does not match the signature content will be considered invalid). If the token inspection is correct, it will be released. If the inspection is wrong, the request will be rejected.

Below is the generation and verification of token, where secret is the key set by yourself (it is a string, and my key cannot be posted publicly).

token generation process:

 public static String generate(String roomid){
        String token = "";
        try{
            Algorithm algorithm = Algorithm.HMAC256(secret);
            Map<String,Object> map = new HashMap<>();
            map.put("roomid",roomid);
            token = JWT.create().withIssuer("auth0")
                    .withPayload(map)
                    .withExpiresAt(new Date(System.currentTimeMillis() + (long)3600*1000))
                    .sign(algorithm);
        }catch(JWTCreationException e){
            e.printStackTrace();
        }
        return token;
    }

For the verification of token, roomid is returned if the verification passes, and null is returned if the verification fails.

public static String validate(String roomid, String token){
        DecodedJWT jwt = null;
        try{
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier jwtVerifier = JWT.require(algorithm)
                    .withClaim("roomid",roomid)
                    .withIssuer("auth0").build();
            jwt = jwtVerifier.verify(token);
            if (jwt == null )return null;
            Claim claim = jwt.getClaim("roomid");
            if (claim == null )return null;
            return claim.asString();
        }catch (JWTVerificationException e){
            return null;
        }

    }

reference resources: https://github.com/auth0/java-jwt

Posted by rn14 on Sun, 03 Oct 2021 12:25:19 -0700