Meet is fate, pass by a praise ^


Source: https://github.com/yulc-coding/java-note/tree/master/jwt

introduce

JWT is a concise, URL-safe declarative specification for passing secure information between communicating parties, often used for cross-domain authentication. Because of the existence of digital signature, it can play the role of anti-string change

Traditional Session mode

Compared with traditional session authentication, sessions are usually stored on the server and maintained by the server. In addition, in the case of server clusters or cross-domain request services, sessions need to be shared so that each server can read sessions. For example, session persistence increases the cost.

JWT token mode

After the user logs in, the server generates a token and returns the token to the client. Each time the client initiates a request, the client obtains the token from the token server and verifies the validity of the token authentication

format

  • The Header Header information
{

  "alg""Algorithm encryption method: HS256".

  "cty""Content Type ".

  "typ""Type" ,

  "kid""Key Id"

 }

Copy the code
  • Payload Indicates the Payload information
{

  "iss""Issuer of the JWT".

  "aud""Audience to accept JWT side".

  "sub""Subject JWT Subject".

  "exp""Expiration Time JWT Expiration Time".

  "nbf""Not Before the JWT is available between XXX".

  "iat""Issued At the time of issuance of the JWT".

  "jti""JWT ID Unique identifier of the JWT".

  "xxx""Custom Properties"

}

Copy the code
  • Signature Signature information = Encryption algorithm (Header + “.” + payload, key)

  • TOKEN

base64(Header).base64(Payload).Signature

Copy the code

code

pom

    <! -- JWT support -->

    <dependency>

        <groupId>com.auth0</groupId>

        <artifactId>java-jwt</artifactId>

        <version>3.8.3</version>

    </dependency>



    <! Json and AES encryption -->

    <dependency>

        <groupId>cn.hutool</groupId>

        <artifactId>hutool-all</artifactId>

        <version>5.0.3</version>

    </dependency>

Copy the code

Create a token

You can pass in publicly declared fields or custom fields

   / * *

* create a token

     *

     * @paramJson requires token parameters. Multiple parameters can be encapsulated as JSON or map

     * @return token

* /


    public static String createToken(JSONObject json) {

        try {

            // Encryption mode

            Algorithm algorithm = Algorithm.HMAC256(SECRET);

            return JWT.create()

                    .withSubject(json.toString())

                    .withIssuer("ylc")

                    // Set the expiration time to 1 minute later

                    .withExpiresAt(DateUtil.offsetMinute(new Date(), 1))

                    .withClaim("customString"."Custom parameters")

                    .withArrayClaim("customArray".new Integer[]{1.2.3})

                    .sign(algorithm);

        } catch (JWTCreationException exception) {

            //Invalid Signing configuration / Couldn't convert Claims.

            System.out.println(exception.getMessage());

            return null;

        }

    }

Copy the code

Token check

The options are as follows: Format verification: header.paypay. signature Encryption mode verification: ALG value of the header Signature information Signature Verification, which prevents data from being tampered With. Verifies the expiration time of public declared fields in payload, such as ISS, JTI, and exp

    / * *

* Verify token validity

     *

     * @param token to verify.

* /


    public static boolean verifyToke(String token) {

        try {

            Algorithm algorithm = Algorithm.HMAC256(SECRET);

            JWTVerifier verifier = JWT.require(algorithm)

                    // Verify that the issuer is the same

                    .withIssuer("ylc")

                    .build();

            / *

* check:

* Format verification: header.paypay.signature

* Encryption mode Verifies the ALG in the Header

* Signature information verification, anti-string change

* Verify the public declaration field Payload

* /


            verifier.verify(token);

            return true;

        } catch (JWTVerificationException exception) {

            //Invalid signature/claims

            System.out.println(exception.getMessage());

            return false;

        }

    }

Copy the code

Parsing the token

All claim fields can be obtained by jwt.getClaims() or by jwt.getClaim(name) with the specified name

/ * *

* parsed token

 *

 * @param token to decode.

* /


public static void decodeToken(String token{

    try {

        DecodedJWT jwt = JWT.decode(token);

        Map<String, Claim> claims = jwt.getClaims();

        Claim customStringClaim = claims.get("customString");

        Claim customArrayClaim = claims.get("customArray");



        String issuer = jwt.getIssuer();

        String subject = jwt.getSubject();



        System.out.println(customStringClaim.asString());

        System.out.println(Arrays.toString(customArrayClaim.asArray(Integer.class)));

        System.out.println(issuer);

        System.out.println(JSONUtil.parseObj(subject));



    } catch (JWTDecodeException exception) {

        //Invalid token

        System.out.println(exception.getMessage());

    }

}

Copy the code

disadvantages

  • By default, the generated token is not encrypted. Others can parse the token to obtain the data in the token. To transmit sensitive information, you can encrypt the information before adding it to the token, or encrypt the generated token
  • Each time the validity period of a token is extended, a new token is generated and the original token needs to be replaced by the front-end
  • Since the server does not store session state, it is not possible to revoke a token or change the permission of the token during use. That is, once a JWT is issued, it will remain valid until it expires, requiring business logic to be set up on the server to handle it.

Please focus on