一、什麼是JWT
JSON Web Token (JWT)是一種安全的,開放的標準(RFC 7519),用於在雙方之間傳輸信息。JWT包含了三部分,分別是Header,Payload和Signature。
Header通常包含兩部分,算法和類型。算法指定加密算法,類型指定JWT類型,最常見的是JWT。
Payload是JWT最重要的部分,包含了Claim,Claim是要傳輸的數據,常見的有:iss(Issuer),iat(Issued At),exp(Expiration Time),sub(Subject),aud(Audience)等,Claim可以被加密。
Signature是將Header和Payload進行加密後的結果,Signature的作用是驗證JWT的合法性。
二、在Spring Boot中使用JWT
1. 引入依賴
在pom.xml中添加以下依賴,這裡使用的是io.jsonwebtoken:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2. 創建JWT工具類
我們需要創建一個工具類來生成和驗證JWT,其中包含了JWT的生成和解析方法。
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component
public class JwtUtils {
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private long expiration;
private Key key;
@PostConstruct
public void init() {
key = Keys.hmacShaKeyFor(secret.getBytes());
}
public String generateToken(String username, String role) {
Map claims = new HashMap();
claims.put("username", username);
claims.put("role", role);
return Jwts.builder()
.setClaims(claims)
.setExpiration(new Date(System.currentTimeMillis() + expiration))
.signWith(key, SignatureAlgorithm.HS512)
.compact();
}
public Claims parseToken(String token) {
return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();
}
}
3. 創建登錄和鑒權接口
我們需要創建一個/login接口來進行用戶登錄,使用POST方法提交用戶名和密碼,之後驗證用戶信息,生成JWT並返回給客戶端。還需要創建一個校驗接口,使用JWT進行鑒權,如果JWT合法,返回200,否則返回401。
@RestController
public class AuthController {
@Autowired
private JwtUtils jwtUtils;
@PostMapping("/login")
public ResponseEntity login(@RequestBody User user) {
if ("admin".equals(user.getUsername()) && "123456".equals(user.getPassword())) {
String token = jwtUtils.generateToken(user.getUsername(), "admin");
return ResponseEntity.ok(token);
}
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
@GetMapping("/auth")
public ResponseEntity auth(HttpServletRequest request) {
String token = request.getHeader("Authorization");
if (StringUtils.isBlank(token)) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
try {
Claims claims = jwtUtils.parseToken(token);
String username = claims.get("username", String.class);
String role = claims.get("role", String.class);
return ResponseEntity.ok().build();
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
}
}
三、JWT的安全性
JWT的安全性很大一部分依賴於secret(加密密鑰)的安全性,由於JWT是可解密的,所以secret在使用中要嚴格保密。另外,JWT也有一些缺點:
- JWT不適合存儲敏感數據。
- 如果一個JWT被盜用,那麼所有在有效期內的請求都是可以通過的,因此我們需要設置JWT的有效期盡量短。
- JWT無法撤銷,如果需要取消某個JWT的訪問授權,需要等待其過期或者在服務端的黑名單上維護該JWT。
四、小結
通過本文,我們了解了JWT的結構和原理,掌握了在Spring Boot中使用JWT的方法,並介紹了JWT的安全性和一些限制。在實際的項目中,我們可以根據具體的需求選擇合適的鑒權方式,在保障系統安全的前提下,提高用戶體驗。
原創文章,作者:YJROO,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/331853.html