Java JWT基本操作

JWT工具类

typescript 复制代码
mport io.jsonwebtoken.*;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;

public class JWTUtils {

    // TOKEN的有效期一个小时(S)
    private static final int TOKEN_TIME_OUT = 3_600 ;
    // 加密KEY
    private static final String TOKEN_ENCRY_KEY = "ABCD";
    // 最小刷新间隔(S)
    private static final int REFRESH_TIME = 300;

    // 生产ID
    public static String getToken(Long id){
        Map<String, Object> claimMaps = new HashMap<>();
        claimMaps.put("id",id);
        long currentTime = System.currentTimeMillis();
        return Jwts.builder()
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(new Date(currentTime))  //签发时间
                .setSubject("description")  //说明
                .setIssuer("xyy") //签发者信息
                .setAudience("admin")  //接收用户
                .compressWith(CompressionCodecs.GZIP)  //数据压缩方式
                .signWith(SignatureAlgorithm.HS512, generalKey()) //加密方式
                .setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000))  //过期时间戳
                .addClaims(claimMaps) //cla信息
                .compact();
    }

    /**
     * 获取token中的claims信息
     *
     * @param token
     * @return
     */
    private static Jws<Claims> getJws(String token) {
        return Jwts.parser()
                .setSigningKey(generalKey())
                .parseClaimsJws(token);
    }

    /**
     * 获取payload body信息
     *
     * @param token
     * @return
     */
    public static Claims getClaimsBody(String token) {
        try {
            return getJws(token).getBody();
        }catch (ExpiredJwtException e){
            return null;
        }
    }

    /**
     * 获取hearder body信息
     *
     * @param token
     * @return
     */
    public static JwsHeader getHeaderBody(String token) {
        return getJws(token).getHeader();
    }

    /**
     * 是否过期
     *
     * @param claims
     * @return -1:有效,0:有效,1:过期,2:过期
     */
    public static int verifyToken(Claims claims) {
        if(claims==null){
            return 1;
        }
        try {
            claims.getExpiration()
                    .before(new Date());
            // 需要自动刷新TOKEN
            if((claims.getExpiration().getTime()-System.currentTimeMillis())>REFRESH_TIME*1000){
                return -1;
            }else {
                return 0;
            }
        } catch (ExpiredJwtException ex) {
            return 1;
        }catch (Exception e){
            return 2;
        }
    }

    /**
     * 由字符串生成加密key
     *
     * @return
     */
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes());
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

内容打印

csharp 复制代码
public class ResultTest {

    public static void main(String[] args) {
        // eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQrDIBBF7zLrCA6a0eQ2xlGYQttQDSSE3r3jorvHf__d8OgCK6DlmX1lUzAvxlc_m2jrYjJFQhdwI_QwgaQOK1IMZF2IdoJ2bFpzafkje5f3a5xa0-28LuV0sHLipwxTzv2fBzdyUYvfH4GZVoyFAAAA.5dtA7NVIyITnHKjYidIej9v2o9wdxkhrqH_lXqTbRgJVQ-h3hC7QPhzWnMeABxgUadedJyjaPcYSiE7Yr63oEw
        String token = JWTUtils.getToken(1L);
        // 根据id生成token
        System.out.println("根据id生成token为"+token);

        JwsHeader header = JWTUtils.getHeaderBody(token);
        // 输出头部信息
        System.out.println("头部信息"+header);

        Claims body = JWTUtils.getClaimsBody(token);
        // 输出详情信息
        System.out.println("详情信息"+body);

        String exp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(body.getExpiration());
        // 输出Body的过期时间
        System.out.println("过期时间"+exp);

        int result = JWTUtils.verifyToken(body);
        // 根据body校验是否过期
        System.out.println("token状态为"+result);
    }

}
ini 复制代码
根据id生成token为eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQrDIBBF7zLrCI4mo8ltjGZgCm1DNZAQeveOi-4e__13w6MJLMDWBsduNhZzNuM8oUmeyfiS2TGuGCeEASQ1WJBiIDsGogHqsWpdtpo_sjd5v_qpVt3O61JOR1FO5SndbOf-z6PvuajF7w8AVTI8hQAAAA.Tkj3Dtn6Y9FhxohvQSmEU5Ze4AGaiI5NhEC2J4uDC_U3Ke6ePiOjNnWgW99jnljoOBqGh4RcbO4SZjR3lwd55w
头部信息{alg=HS512, zip=GZIP}
详情信息{jti=f0072f29-01cc-4951-a3f6-3dcf2f1b1851, iat=1687604766, sub=description, iss=xyy, aud=admin, exp=1687608366, id=1}
过期时间2023-06-24 20:06:06
token状态为-1

案例

用户登录

less 复制代码
@Transactional
@Slf4j
@Service
public class ApUserServiceImpl extends ServiceImpl<ApUserMapper, ApUser> implements ApUserService {
    @Override
    public ResponseResult login(LoginDto dto) {
        // 正式登录,用户名和密码
        if(StringUtils.isNotBlank(dto.getPhone())&&StringUtils.isNotBlank(dto.getPassword())){
            //手机号 - > 用户信息
            ApUser apUser = getOne(Wrappers.<ApUser>lambdaQuery().eq(ApUser::getPhone, dto.getPhone()));
            if(apUser == null){
                return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"用户信息不存在");
            }
            // 比对密码
            String salt = apUser.getSalt();
            String password = dto.getPassword();
            String pwd = DigestUtils.md5DigestAsHex((password + salt).getBytes());
            if(!pwd.equals(apUser.getPassword())){
                return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR);
            }
            // 返回数据  jwt
            String token = AppJwtUtil.getToken(Long.valueOf(apUser.getId()));
            Map<String,Object> map = new HashMap<>();
            map.put("token",token);
            apUser.setSalt("");
            apUser.setPassword("");
            map.put("user",apUser);

            return ResponseResult.okResult(map);
        }else {
            // 游客登录
            HashMap<String, Object> map = new HashMap<>();
            map.put("token",AppJwtUtil.getToken(0L));
            return ResponseResult.okResult(map);
        }
    }
}

网关校验

scss 复制代码
@Slf4j
@Component
public class AuthorizeFilter implements Ordered, GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取request和response
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        // 判断是否是登录
        if(request.getURI().getPath().contains("/login")){
            //放行
            return chain.filter(exchange);
        }
        // 获取token
        String token = request.getHeaders().getFirst("token");
        // 判断token是否存在
        if(StringUtils.isBlank(token)){
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        // 判断token是否有效
       try{
            Claims claimsBody = AppJwtUtil.getClaimsBody(token);
            //是否是过期
            int result = AppJwtUtil.verifyToken(claimsBody);
            if(result==1||result==2){
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
        }catch(Exception e){
            e.printStackTrace();
           response.setStatusCode(HttpStatus.UNAUTHORIZED);
           return response.setComplete();
        }
        //放行
        return chain.filter(exchange);

    }

    @Override
    public int getOrder() {
        return 0;
    }
}
相关推荐
草莓base17 分钟前
【手写一个spring】spring源码的简单实现--容器启动
java·后端·spring
Ljw...32 分钟前
表的增删改查(MySQL)
数据库·后端·mysql·表的增删查改
编程重生之路33 分钟前
Springboot启动异常 错误: 找不到或无法加载主类 xxx.Application异常
java·spring boot·后端
薯条不要番茄酱33 分钟前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea
qq_17448285759 小时前
springboot基于微信小程序的旧衣回收系统的设计与实现
spring boot·后端·微信小程序
锅包肉的九珍9 小时前
Scala的Array数组
开发语言·后端·scala
心仪悦悦9 小时前
Scala的Array(2)
开发语言·后端·scala
2401_8827275710 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
心仪悦悦10 小时前
Scala中的集合复习(1)
开发语言·后端·scala
阿芯爱编程10 小时前
商品折扣后的最终价格单调栈
java·后端·算法