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;
    }
}
相关推荐
二闹5 分钟前
三个注解,到底该用哪一个?别再傻傻分不清了!
后端
用户490558160812517 分钟前
当控制面更新一条 ACL 规则时,如何更新给数据面
后端
林太白18 分钟前
Nuxt.js搭建一个官网如何简单
前端·javascript·后端
码事漫谈20 分钟前
VS Code 终端完全指南
后端
该用户已不存在1 小时前
OpenJDK、Temurin、GraalVM...到底该装哪个?
java·后端
怀刃1 小时前
内存监控对应解决方案
后端
码事漫谈1 小时前
VS Code Copilot 内联聊天与提示词技巧指南
后端
Moonbit1 小时前
MoonBit Perals Vol.06: MoonBit 与 LLVM 共舞 (上):编译前端实现
后端·算法·编程语言
Moonbit1 小时前
MoonBit Perals Vol.06: MoonBit 与 LLVM 共舞(下):llvm IR 代码生成
后端·程序员·代码规范
Moonbit2 小时前
MoonBit Pearls Vol.05: 函数式里的依赖注入:Reader Monad
后端·rust·编程语言