在本篇文章中,如何在Java项目中使用JSON Web Tokens (JWT) 进行用户认证与授权。JWT是一种轻量级的身份认证机制,它被广泛应用于现代Web应用和API服务中。
在现代Web应用中,用户认证和信息交换变得越来越重要。为了实现安全且高效的身份验证,JSON Web Token(JWT)成为了常见的选择。JWT是一种轻量级的、安全的认证方式,广泛应用于API认证、单点登录(SSO)等场景。本文将介绍JWT的基本概念、结构及其工作原理,帮助你理解如何利用JWT实现安全的用户认证。
JWT(JSON Web Token) 是一种开放标准(RFC 7519),用于在网络应用环境中传递声明(Claims)。它的核心优势在于能够安全、简洁地传递信息,通常用于身份验证和信息交换。
JWT是一种由三部分组成的字符串:头部(Header)、负载(Payload)和签名(Signature)。这三部分通过.
(点)连接在一起,形成一个token。JWT的最大特点之一是它可以通过数字签名验证信息的完整性和来源。
JWT由三部分构成:
JWT的头部通常包含两部分信息:
例如,头部可能看起来像这样:
json{
"alg": "HS256",
"typ": "JWT"
}
负载部分包含声明(Claims),这些声明是关于实体(如用户)以及其他一些数据的。声明可以是公开的或私有的。
常见的声明有:
例如,负载可以是这样的:
json{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
为了确保JWT的完整性和来源的可信性,JWT需要通过签名进行验证。签名的生成方式如下:
scssHMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
签名保证了JWT在传输过程中没有被篡改。
JWT的工作流程大致如下:
用户登录:用户通过用户名和密码向服务器请求身份验证。
生成JWT:服务器验证成功后,生成JWT,并将其返回给客户端。
存储JWT:客户端将JWT存储在本地(通常是LocalStorage或Cookie)。
发送请求:在后续的请求中,客户端将JWT附加在HTTP请求的Authorization头中,格式为:
Authorization: Bearer <token>
验证JWT:服务器接收到请求后,会验证JWT的合法性。如果JWT有效,服务器会处理请求;否则,返回错误。
为了简化JWT的生成和验证,我们可以创建一个工具类 JWTUtil
。以下是一个使用 Java 和 JJWT库 编写的简单JWT工具类示例:
javaimport io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
public class JWTUtil {
// 密钥(用于签名JWT)
private static final String SECRET_KEY = "your-256-bit-secret";
// JWT过期时间(单位:毫秒)
private static final long EXPIRATION_TIME = 86400000; // 24小时
// 生成JWT
public static String createJWT(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date()) // 签发时间
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) // 过期时间
.signWith(SignatureAlgorithm.HS256, SECRET_KEY) // 使用HS256算法进行签名
.compact();
}
// 解析JWT
public static Claims parseJWT(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
}
// 获取用户名(从JWT中解析)
public static String getUsernameFromJWT(String token) {
Claims claims = parseJWT(token);
return claims.getSubject(); // 返回JWT的"sub"字段值
}
// 校验JWT是否过期
public static boolean isExpired(String token) {
Claims claims = parseJWT(token);
return claims.getExpiration().before(new Date()); // 检查当前时间是否在过期时间之前
}
}
JWTUtil
类生成JWT
你可以使用 JWTUtil.createJWT()
方法来生成一个包含用户名的JWT,示例如下:
String token = JWTUtil.createJWT("john_doe"); System.out.println("Generated JWT: " + token);
解析JWT
使用 JWTUtil.parseJWT()
方法解析JWT并获取Claims,示例如下:
Claims claims = JWTUtil.parseJWT(token); System.out.println("Username from JWT: " + claims.getSubject());
校验JWT是否过期
使用 JWTUtil.isExpired()
方法来校验JWT是否已经过期,示例如下:
boolean isExpired = JWTUtil.isExpired(token); System.out.println("Is the token expired? " + isExpired);
SECRET_KEY
是一个保密的字符串,保证只有服务端能知道,以防止JWT被伪造。SECRET_KEY
可以通过配置文件或环境变量来存储,而不是硬编码在代码中。EXPIRATION_TIME
也应根据实际需求进行设置。本文作者:Sundaze
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!