JWT 用户认证实现
2025/11/30大约 3 分钟
登录认证
一、JWT 基础知识
1.1 什么是 JWT?
JWT (JSON Web Token) 是一种基于 JSON 的开放标准(RFC 7519),用于在网络应用环境间安全地传递信息。它是一种无状态的认证方式——>服务器不需要保存会话信息。
1.2 JWT 的结构
JWT 由三部分组成,使用 . 分隔:
Header.Payload.Signature完整示例:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c1. Header(头部)
包含令牌的类型和使用的签名算法,不加密仅使用Base64Url编码,可以查看。
{
"alg": "HS256",
"typ": "JWT"
}2. Payload(载荷)
包含声明信息(用户信息、权限等),不加密仅使用Base64Url编码,可以查看。
载荷部分可以直接获取用户信息不查数据库,不能放敏感信息。
{
"sub": "1234567890",
"name": "John Doe",
"userId": 1,
"role": "admin",
"iat": 1516239022,
"exp": 1516242622
}常用的标准声明:
iss: 发行者sub: 主题aud: 受众exp: 过期时间iat: 签发时间jti: JWT ID
3. Signature(签名)
用于验证消息的完整性,签名会对头部和负载,使用头部声明的单向算法通过密钥进行签名。
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)二、Maven 依赖
2.1 添加 JWT 依赖
在 pom.xml 中添加:
<properties>
<jjwt.version>0.11.5</jjwt.version>
</properties>
<dependencies>
<!-- JWT 依赖 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
</dependencies>三、JWT工具类
public class JwtUtil {
/**
* 生成jwt
* 使用Hs256算法, 私匙使用固定秘钥
*
* @param secretKey jwt秘钥
* @param ttlMillis jwt过期时间(毫秒)
* @param claims 设置的信息
* @return
*/
public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) {
if(secretKey.length()<32)
throw new BaseException(JWT_SECRETKEY_LENGTH_TOO_SHORT.getCode(),JWT_SECRETKEY_LENGTH_TOO_SHORT.getMessage());
// 生成签名密钥
SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));
// 生成JWT的过期时间
long expMillis = System.currentTimeMillis() + ttlMillis;
Date exp = new Date(expMillis);
// 构建JWT
return Jwts.builder()
.claims(claims) // 设置私有声明
.expiration(exp) // 设置过期时间
.signWith(key) // 使用密钥签名
.compact();
}
/**
* Token解密
*
* @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个
* @param token 加密后的token
* @return
*/
public static Claims parseJWT(String secretKey, String token) {
if(secretKey.length()<32)
throw new BaseException(JWT_SECRETKEY_LENGTH_TOO_SHORT.getCode(),JWT_SECRETKEY_LENGTH_TOO_SHORT.getMessage());
// 生成签名密钥
SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));
// 解析JWT
return Jwts.parser()
.verifyWith(key) // 设置验证密钥
.build()
.parseSignedClaims(token) // 解析签名后的token
.getPayload(); // 获取载荷
}
}JWT配置和属性类
配置
application.yml:
belnuan:
jwt:
# 管理端
# 设置jwt签名加密时使用的秘钥(至少32个字符,256位)
user-secret-key: belnuan2025SecretKeyForJWTTokenGeneration123456789
# 设置jwt过期时间
user-ttl: 7200000
# 设置前端传递过来的令牌名称
user-token-name: token属性配置类
方便获取属性值,ttl,secretkey等。
@Component
@ConfigurationProperties(prefix = "sky.jwt")
@Data
public class JwtProperties {
/**
* 管理端员工生成jwt令牌相关配置
*/
private String adminSecretKey;
private long adminTtl;
private String adminTokenName;
/**
* 用户端微信用户生成jwt令牌相关配置
*/
private String userSecretKey;
private long userTtl;
private String userTokenName;
}