java之JWT认证、JWT拦截器、JWT工具类、日期工具类

1、依赖

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

2、JWT工具类

package com.jay.SpringBootStudy8.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.HashMap;

/**
 * Jwt工具类
 */
public class JwtUtil {
    //自定密钥,最好搞长一点
    public static final String tokenKey = "jay2021";
    /*
    生成票证
     */
    public static String getSign(HashMap<String,Object> headMap,HashMap<String,String> claimMap,int days){
        LocalDateTime localDateTime = LocalDateTime.now().plus(days, ChronoUnit.DAYS);
        Date date = LocalDateTimeUtil.localDateTimeToDate(localDateTime);
        JWTCreator.Builder builder = JWT.create().withHeader(headMap);
        claimMap.forEach((key, value) -> {
            builder.withClaim(key, value);
        });
        builder.withExpiresAt(date);
        String token = builder.sign(Algorithm.HMAC256(tokenKey));
        return token;
    }
    /*
    获取token信息,token不对会异常
     */
    public static DecodedJWT verify(String token){
        DecodedJWT verify = JWT.require(Algorithm.HMAC256(tokenKey)).build().verify(token);
        return verify;
    }
}

3、日期工具类LocalDateTimeUtil

package com.jay.SpringBootStudy8.utils;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;

public class LocalDateTimeUtil {
    /**
     * LocalDateTime转毫秒时间戳
     * @param localDateTime LocalDateTime
     * @return 时间戳
     */
    public static Long localDateTimeToTimestamp(LocalDateTime localDateTime) {
        try {
            ZoneId zoneId = ZoneId.systemDefault();
            Instant instant = localDateTime.atZone(zoneId).toInstant();
            return instant.toEpochMilli();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 时间戳转LocalDateTime
     * @param timestamp 时间戳
     * @return LocalDateTime
     */
    public static LocalDateTime timestampToLocalDateTime(long timestamp) {
        try {
            Instant instant = Instant.ofEpochMilli(timestamp);
            ZoneId zone = ZoneId.systemDefault();
            return LocalDateTime.ofInstant(instant, zone);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Date转LocalDateTime
     * @param date Date
     * @return LocalDateTime
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        try {
            Instant instant = date.toInstant();
            ZoneId zoneId = ZoneId.systemDefault();
            return instant.atZone(zoneId).toLocalDateTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * LocalDateTime转Date
     * @param localDateTime LocalDateTime
     * @return Date
     */
    public static Date localDateTimeToDate(LocalDateTime localDateTime) {
        try {
            ZoneId zoneId = ZoneId.systemDefault();
            ZonedDateTime zdt = localDateTime.atZone(zoneId);
            return Date.from(zdt.toInstant());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

4、JWT拦截器,在请求头的Authorization中携带token

package com.jay.SpringBootStudy8.config;

import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jay.SpringBootStudy8.utils.JwtUtil;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.HashMap;

public class JWTInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler) throws Exception {
        HashMap<String,Object> res = new HashMap<>();
        res.put("state",false);
        String authStr = request.getHeader("Authorization");
        try {
            DecodedJWT verify = JwtUtil.verify(authStr);
            res.put("state",true);
            return true;
        }catch (SignatureVerificationException e) {
            e.printStackTrace();//无效签名
            res.put("msg","无效签名");
        }catch (TokenExpiredException e){
            e.printStackTrace();//token过期
            res.put("msg","token过期");
        }catch (AlgorithmMismatchException e){
            e.printStackTrace();//算法不一致
            res.put("msg","算法不一致");
        }catch (Exception e){
            e.printStackTrace();//token无效
            res.put("msg","token无效");
        }
        String json = new ObjectMapper().writeValueAsString(res);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
        return false;
    }
}

5、注册拦截器

package com.jay.SpringBootStudy8.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CustomerMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new JWTInterceptor()).addPathPatterns("/scanner/getCompanies");
    }
}

6、登录生成token、获取token信息、验证拦截器,登录使用的是Shiro

package com.jay.SpringBootStudy8.controller;

import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.jay.SpringBootStudy8.pojo.SysUser;
import com.jay.SpringBootStudy8.utils.JwtUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class ScannerController {
    /*
    登录,生成token
     */
    @PostMapping("/scanner/login")
    public HashMap<String,Object> login(String name, String pwd) {
        HashMap<String,Object> res = new HashMap<>();
        res.put("state",false);
        //MD5加密
        ByteSource credentialsSalt = ByteSource.Util.bytes(name);
        Object obj = new SimpleHash("MD5", pwd, credentialsSalt, 1);
        String pwd2 = obj.toString();
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //封装登录数据
        UsernamePasswordToken token = new UsernamePasswordToken(name, pwd2);
        try {
            //执行登录方法
            subject.login(token);
            Session session = subject.getSession();
            SysUser user = (SysUser) session.getAttribute("user");
            // 登录成功,生成票证
            HashMap<String,Object> headMap = new HashMap<>();
            HashMap<String,String> claimMap = new HashMap<>();
            claimMap.put("userId",Integer.toString(user.getId()));
            claimMap.put("userName",user.getUserName());
            String signStr = JwtUtil.getSign(headMap,claimMap,7);
            res.put("state",true);
            res.put("msg","登录成功");
            res.put("token",signStr);
        } catch (UnknownAccountException e) {
            res.put("msg","用户名不存在");
        } catch (IncorrectCredentialsException e) {
            res.put("msg","密码错误");
        }
        return res;
    }
    /*
    获取token信息
     */
    @PostMapping("/scanner/checkToken")
    public Map<String, String> checkToken(@RequestHeader("Authorization")String authStr){
        DecodedJWT verify = JwtUtil.verify(authStr);
        Map<String, Claim> claims = verify.getClaims();
        Map<String,String> res = new HashMap<>();
        claims.forEach((key,value)->{
            res.put(key,value.asString());
        });
        return res;
    }
    /*
    拦截请求
     */
    @PostMapping("/scanner/getCompanies")
    public Map<String,String> getCompanies(){
        Map<String,String> res = new HashMap<>();
        res.put("ali","阿里巴巴");
        res.put("baidu","百度");
        return  res;
    }
}

  视频:https://www.bilibili.com/video/BV1i54y1m7cP?p=1

原文地址:https://www.cnblogs.com/xsj1989/p/15176803.html