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;
    }
}
相关推荐
哎呦没13 分钟前
SpringBoot框架下的资产管理自动化
java·spring boot·后端
2401_8576009516 分钟前
SpringBoot框架的企业资产管理自动化
spring boot·后端·自动化
NiNg_1_2344 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
Chrikk6 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*6 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue6 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man6 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang
customer088 小时前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源