JWT实现拦截器和token认证

文章目录

  • 一、导入依赖
  • 二、使用教程
      • 1.Jwt工具
      • 2.拦截规则
      • 3.拦截器编写
      • 4.登录接口
      • 5.测试
  • 注意

一、导入依赖

  Jwt全称为json web token,是跨域的支持各种语言、一般有三个部分头部(header)、载荷(payload)、签名(signature)

功能如下:
  1.头部放签名算法和令牌类型
  2.载荷放你想放的信息,如账号啥的,令牌之后就可以直接从这里获取信息不用再查数据库
  3.签名放前两部分的签名,防止数据篡改

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

二、使用教程

1.Jwt工具

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

public class JwtUtils {
    /**
     * @param userId
     * @param sign
     * @return 以userId作为载荷,获取一个token
     */
    public static String getToken(String userId, String password){
        //将userId保存到token作为载荷
        return JWT.create().withAudience(userId)
                .withExpiresAt(DateUtil.offsetHour(new Date(),24))
                .sign(Algorithm.HMAC256(password));
    }
}

withAudience()可以放用户名、账户id之类的,这样就不用查询数据库了
withExpiresAt()放token的过期时间,上面的表示token24小时之后过期
sign()放签名认证,一般是放加密后的密码

2.拦截规则

import com.group.oayouth.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 {

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

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/user/login","/user/register","/**/excel","/**/import");
    }
}

addPathPatterns() 放要拦截的接口
excludePathPatterns()放开放的接口
上面代码的意思是拦截除了开放接口以外的所以接口

3.拦截器编写

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.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.group.oayouth.entity.User;
import com.group.oayouth.service.IUserService;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

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

public class JwtInterceptor implements HandlerInterceptor {

    @Resource
    private  IUserService userService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 从 http 请求头中取出 token
        String token = request.getHeader("token");
        // 如果不是映射到方法直接通过
        if(!(handler instanceof HandlerMethod)){
            return true;
        }

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

        // 验证 token
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
        try {
            jwtVerifier.verify(token);
        } catch (JWTVerificationException e) {
            throw new RuntimeException("token失效,请重新登录");
        }

        return true;
    }
}

4.登录接口

这里自由发挥了图片仅供参考,把你的token放进进登录的实体类就行。
我这里密码用了md5加密,所以你的password放进token之前也要先加密一下
JWT实现拦截器和token认证_第1张图片

JWT实现拦截器和token认证_第2张图片
JWT实现拦截器和token认证_第3张图片

5.测试

调用没放行的接口出现以下情况说明成功,记得捕获异常哈
JWT实现拦截器和token认证_第4张图片

注意

你配置的swagger那些公共模块的网址也要放行,不然会被拦截掉

你可能感兴趣的:(JWT实现拦截器和token认证)