SpringBoot: Integrating JWT

SpringBoot: Integrating JWT

JWT: is a concise, URL-safe representational statement specification for passing secure information between two parties. As an open standard (RFC 7519), JWT defines a concise, self-contained method for securely transferring information in the form of Json objects between communicating parties.

The characteristics of JWT: concise (small data volume, fast transmission speed), self-contained (the load contains all the information needed by users, avoiding multiple query databases).

The composition of JWT: Header (head), Payload (load), Signature (signature), separated by periods in English.

  1. head:

    Contains two parts: token type and encryption algorithm used.

    {
      "alg": "HS256",
      "typ": "JWT"
    }
    

    Encode the above content with base64 to get the JWT header.

  2. load:

    iss: the issuer of the JWT
    sub: the user the JWT is for
    aud: the party receiving the JWT
    exp(expires): when it expires, here is a Unix timestamp
    iat(issued at): when it was issued

    In addition to the standard definition, it is also necessary to define the fields that need to be used in business processing, such as user token or id

    {
          
          
        "iss": "Lefto.com",
        "iat": 1500218077,
        "exp": 1500218077,
        "aud": "www.leftso.com",
        "sub": "[email protected]",
        "user_id": "dc2c4eefe2d141490b6ca612e252f92e",
        "user_token": "09f7f25cdb003699cee05759e7934fb2"
    }
    
  3. sign:

    The signature is actually a signature verification of the JWT header and payload integration.

JWT dependencies:

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

Springboot gets the token (usually placed in utils, and the generated token is returned when logging in):

import cn.hutool.core.date.DateUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;

import java.util.Date;

public class TokenUtils {
    
    
    /*
    *生成token
    *
    * */
    public static String genToken(String userId, String sign) {
    
    
        return JWT.create().withAudience(userId) // 将 user id 保存到 token 里面,作为载荷
                .withExpiresAt(DateUtil.offsetHour(new Date(), 2)) //2小时候后token过期
                .sign(Algorithm.HMAC256(sign)); // 以 password 作为 token 的密钥
    }
}

The front end integrates the token into the request request (after the integration, every time a request is sent, the token will be automatically brought):

request.interceptors.request.use(config => {
    
    
    config.headers['Content-Type'] = 'application/json;charset=utf-8';

    config.headers['token'] = user.token;  // 设置请求头
    return config
}, error => {
    
    
    return Promise.reject(error)
});

Token interception (usually placed under the inteceptor folder in config, used to intercept requests and check tokens):

package com.ustb.springboot.config.interceptor;

import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.ustb.springboot.entity.User;
import com.ustb.springboot.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class JwtInterceptor implements HandlerInterceptor {
    
    

    @Autowired
    private UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        String token = request.getHeader("token");
        // 如果不是映射到方法直接通过
        if(!(handler instanceof HandlerMethod)){
    
    
            return true;
        }
        if (StrUtil.isBlank(token)){
    
    
            throw new RuntimeException("无token,请重新登录");
        }

        // 获取 token 中的 user id
        String userId;
        try {
    
    
            userId = JWT.decode(token).getAudience().get(0);
        } catch (JWTDecodeException j) {
    
    
            throw new RuntimeException("401");
        }
        //根据token中的userid查询数据库
        User user = userService.getById(Integer.parseInt(userId));
        if (user == null) {
    
    
            throw new RuntimeException("用户不存在,请重新登录");
        }

        //用户密码加签验证,验证token
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
        try {
    
    
            jwtVerifier.verify(token);  //验证token
        } catch (JWTVerificationException e) {
    
    
            throw new RuntimeException("401");
        }
        return true;
    }
}

Token interception is not performed for some requests (usually placed in the config folder):

package com.ustb.springboot.config;

import com.ustb.springboot.config.interceptor.JwtInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    
    


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    
    
        registry.addInterceptor(newjwtInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/user/login", "/user/register", "/zhuanzheng/export", "/zhuanzheng/import", "/methods/**", "/file/**");    // 拦截所有请求, 决定判断token是否合法来决定是否需要登录
    }

    @Bean
    public JwtInterceptor newjwtInterceptor(){
    
    
        return new JwtInterceptor();
    }
}

Guess you like

Origin blog.csdn.net/no1xiaoqianqian/article/details/127104167