一、什么是JWT
JSON Web Token(JWT)是一种用于安全传输信息的开放标准,基于 JSON 格式定义了一种紧凑且自包含的方式来在各方之间安全地传输信息。JWT 可以被用作验证身份、信息交换的 token。
一个 JWT 由三个部分组成,分别是头部(Header)、载荷(Payload)和签名(Signature):
{
"alg": "HS256",
"typ": "JWT"
}
.
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
其中,头部和载荷都是 JSON 格式,签名是根据特定算法生成的字符串,用于验证 JWT 的可靠性。JWT 的优势在于它既可以存放认证信息,又可以存放其他的业务信息,而且用户信息都加密存储,不需要每次都从数据库中读取用户信息。
二、JWT的使用场景
下面列举了一些 JWT 的常见使用场景:
- 用户身份验证:用户登录后服务器返回 JWT,客户端之后访问其他接口时携带 JWT 作为鉴权凭证。
- 应用程序授权:JWT 用于应用程序内部接口的鉴权授权,例如微服务内部的接口访问。
- 密码重置/邮箱验证等场景:发送 JWT 至用户邮箱或者手机,使用 JWT 验证用户身份并执行相应的操作。
三、实现JWT in Java
首先,我们需要添加相关依赖:
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-jackson -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
接下来,我们可以创建一个 JWTUtil 来处理操作 JWT:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
import java.util.Date;
public class JWTUtil {
/**
* 根据用户信息生成 jwt
*/
public static String generateToken(User user) {
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
JwtBuilder builder = Jwts.builder()
.setId(user.getId())
.setIssuedAt(now)
.setSubject(user.getName())
.setIssuer(user.getName())
.signWith(key);
long ttlMillis = 86400000L; //过期时间为1天
if (ttlMillis >= 0) {
long expMillis = nowMillis + ttlMillis;
Date exp = new Date(expMillis);
builder.setExpiration(exp);
}
return builder.compact();
}
/**
* 根据 jwt 解析用户信息
*/
public static User parseToken(String token) {
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
Claims claims = Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(token)
.getBody();
User user = new User();
user.setId(claims.getId());
user.setName(claims.getSubject());
return user;
}
}
四、使用 JWT 进行授权认证
在使用 JWT 进行授权认证时,通常需要将 JWT 存储在客户端(如浏览器)中,这样可以在下次访问时带上 JWT,从而进行认证。下面是一个使用 JWT 进行授权认证的示例:
@GetMapping("/users/me")
public ResponseEntity currentUser(@RequestHeader(value="Authorization") String token) {
// 从请求头中获取 JWT
if (token.startsWith("Bearer ")) {
token = token.substring(7);
}
// 验证 JWT 并获取用户信息
User user = JWTUtil.parseToken(token);
if (user != null) {
return ResponseEntity.ok(user);
}
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
结语
JWT 是一种非常实用的鉴权方式,它具有跨语言、解耦合等优点。在 Java 中,我们可以使用 jjwt 库来操作 JWT,可以将其用于接口鉴权、用户身份认证等场景。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/227756.html
微信扫一扫
支付宝扫一扫