如何使用Jwt实现登录密令拦截

首先创建一个SpirngBoot模块,导入相应的依赖,再导入JWT的相关依赖:


    com.auth0
    java-jwt
    4.4.0

在创建一个Jwt的工具类:

public class JwtUtil {
    private static final String KEY = "why";

    // 接收业务数据,生成token并返回
    public static String generateToken(Map claims) {
        return JWT.create()
                .withClaim("claims", claims)
                .withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 12))
                .sign(Algorithm.HMAC256(KEY));
    }

    // 接收token,验证token,并返回业务数据
    public static Map parseToken(String token) {
        return JWT.require(Algorithm.HMAC256(KEY))
                .build()
                .verify(token)
                .getClaim("claims")
                .asMap();
    }

 在配置一个拦截器用于拦截访问其他页面的请求,拦截到登录或注册页面:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

//    InterceptorRegistry registry注册器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
//        登录接口和注册接口不拦截
        registry.addInterceptor(loginInterceptor).excludePathPatterns("/users/login","/users/register");
    }
}

编写登录拦截器:

//拦截器
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
//    preHandle方法
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //令牌验证
        String token = request.getHeader("Authorization");

        try {
//            获取redis存的令牌
            String redisToken = stringRedisTemplate.opsForValue().get(token);

            if (redisToken==null){
                throw new RuntimeException();
            }

            Map claims = JwtUtil.parseToken(token);
            //存
            ThreadLocalUtil.set(claims);
            return true;
        }catch (Exception e){
            response.setStatus(401);
            return false;
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // ThreadLocal中的清空数据
        ThreadLocalUtil.remove();
    }
}

再创建一个工具类用于token:

/**
 * ThreadLocal 工具类
 */
public class ThreadLocalUtil {
    // 提供 ThreadLocal 对象
    private static final ThreadLocal THREAD_LOCAL = new ThreadLocal<>();

    // 根据键获取值
    public static  T get() {
        return (T) THREAD_LOCAL.get();
    }

    // 存储键值对
    public static void set(Object value) {
        THREAD_LOCAL.set(value);
    }

    // 清除 ThreadLocal 防止内存泄漏
    public static void remove() {
        THREAD_LOCAL.remove();
    }
}

在登录接口当中存储token:

@PostMapping({"/login"})
public Result findUserAccount(@RequestBody Map requestData) {
    String username = (String)requestData.get("username");
    String password = (String)requestData.get("password");
    User user = this.userService.findUserNamePassword(username, password);
    Integer code = user != null ? Code.GET_OK : Code.GET_ORR;
    String msg = user != null ? "" : "抱歉,你查找的信息不存在!";

    Map claims  = new HashMap<>();
    claims.put("id",user.getId());
    claims.put("username",user.getUsername());
    String token = JwtUtil.generateToken(claims);
    //把token存到reids当中
    redisTemplate.opsForValue().set(token,token,1, TimeUnit.HOURS);

    System.out.println(user);
    return new Result(code, token, msg);
}

 

 

你可能感兴趣的:(java,服务器)