/* * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the dreamlu.net developer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * Author: Chill 庄骞 (smallchill@163.com) */ package org.springblade.core.jwt; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import org.springblade.core.jwt.props.JwtProperties; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.util.StringUtils; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.concurrent.TimeUnit; /** * Jwt工具类 * * @author Chill */ public class JwtUtil { /** * token基础配置 */ public static String BEARER = "bearer"; public static Integer AUTH_LENGTH = 7; /** * token保存至redis的key */ private static final String REFRESH_TOKEN_CACHE = "blade:refreshToken"; private static final String TOKEN_CACHE = "blade:token"; private static final String TOKEN_KEY = "token:state:"; /** * jwt配置 */ private static JwtProperties jwtProperties; /** * redis工具 */ private static RedisTemplate redisTemplate; public static JwtProperties getJwtProperties() { return jwtProperties; } public static void setJwtProperties(JwtProperties properties) { if (JwtUtil.jwtProperties == null) { JwtUtil.jwtProperties = properties; } } public static RedisTemplate getRedisTemplate() { return redisTemplate; } public static void setRedisTemplate(RedisTemplate redisTemplate) { if (JwtUtil.redisTemplate == null) { JwtUtil.redisTemplate = redisTemplate; } } /** * 签名加密 */ public static String getBase64Security() { return Base64.getEncoder().encodeToString(getJwtProperties().getSignKey().getBytes(StandardCharsets.UTF_8)); } /** * 获取请求传递的token串 * * @param auth token * @return String */ public static String getToken(String auth) { if ((auth != null) && (auth.length() > AUTH_LENGTH)) { String headStr = auth.substring(0, 6).toLowerCase(); if (headStr.compareTo(BEARER) == 0) { auth = auth.substring(7); } return auth; } return null; } /** * 解析jsonWebToken * * @param jsonWebToken token串 * @return Claims */ public static Claims parseJWT(String jsonWebToken) { try { return Jwts.parserBuilder() .setSigningKey(Base64.getDecoder().decode(getBase64Security())).build() .parseClaimsJws(jsonWebToken).getBody(); } catch (Exception ex) { return null; } } /** * 获取保存在redis的accessToken * * @param tenantId 租户id * @param userId 用户id * @param accessToken accessToken * @return accessToken */ public static String getAccessToken(String tenantId, String userId, String accessToken) { return String.valueOf(getRedisTemplate().opsForValue().get(getAccessTokenKey(tenantId, userId, accessToken))); } /** * 添加accessToken至redis * * @param tenantId 租户id * @param userId 用户id * @param accessToken accessToken * @param expire 过期时间 */ public static void addAccessToken(String tenantId, String userId, String accessToken, int expire) { getRedisTemplate().delete(getAccessTokenKey(tenantId, userId, accessToken)); getRedisTemplate().opsForValue().set(getAccessTokenKey(tenantId, userId, accessToken), accessToken, expire, TimeUnit.SECONDS); } /** * 删除保存在redis的accessToken * * @param tenantId 租户id * @param userId 用户id */ public static void removeAccessToken(String tenantId, String userId) { removeAccessToken(tenantId, userId, null); } /** * 删除保存在redis的accessToken * * @param tenantId 租户id * @param userId 用户id * @param accessToken accessToken */ public static void removeAccessToken(String tenantId, String userId, String accessToken) { getRedisTemplate().delete(getAccessTokenKey(tenantId, userId, accessToken)); } /** * 获取accessToken索引 * * @param tenantId 租户id * @param userId 用户id * @param accessToken accessToken * @return token索引 */ public static String getAccessTokenKey(String tenantId, String userId, String accessToken) { String key = tenantId.concat(":").concat(TOKEN_CACHE).concat("::").concat(TOKEN_KEY); if (getJwtProperties().getSingle() || StringUtils.isEmpty(accessToken)) { return key.concat(userId); } else { return key.concat(accessToken); } } /** * 获取保存在redis的refreshToken * * @param tenantId 租户id * @param userId 用户id * @param refreshToken refreshToken * @return accessToken */ public static String getRefreshToken(String tenantId, String userId, String refreshToken) { return String.valueOf(getRedisTemplate().opsForValue().get(getRefreshTokenKey(tenantId, userId))); } /** * 添加refreshToken至redis * * @param tenantId 租户id * @param userId 用户id * @param refreshToken refreshToken * @param expire 过期时间 */ public static void addRefreshToken(String tenantId, String userId, String refreshToken, int expire) { getRedisTemplate().delete(getRefreshTokenKey(tenantId, userId)); getRedisTemplate().opsForValue().set(getRefreshTokenKey(tenantId, userId), refreshToken, expire, TimeUnit.SECONDS); } /** * 删除保存在refreshToken的token * * @param tenantId 租户id * @param userId 用户id */ public static void removeRefreshToken(String tenantId, String userId) { getRedisTemplate().delete(getRefreshTokenKey(tenantId, userId)); } /** * 获取refreshToken索引 * * @param tenantId 租户id * @param userId 用户id * @return token索引 */ public static String getRefreshTokenKey(String tenantId, String userId) { return tenantId.concat(":").concat(REFRESH_TOKEN_CACHE).concat("::").concat(TOKEN_KEY).concat(userId); } }