Spring Boot整合JWT實(shí)現(xiàn)認(rèn)證與授權(quán)的項(xiàng)目實(shí)踐
概述
JSON Web Token (JWT) 是一種開(kāi)放標(biāo)準(zhǔn) (RFC 7519),它定義了一種緊湊且自包含的方式,用于在各方之間安全地傳輸信息。在Web應(yīng)用中,JWT常用于身份驗(yàn)證和信息交換。
依賴配置
首先需要在項(xiàng)目中添加JWT依賴:
<!-- JWT依賴 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
JWT工具類封裝
我們創(chuàng)建一個(gè)JwtUtil工具類來(lái)封裝JWT的生成、解析和驗(yàn)證邏輯:
package com.bookstore.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component
public class JwtUtil {
private static final String SECRET_KEY = "bookstore_secret_key";
private static final long EXPIRATION_TIME = 24 * 60 * 60 * 1000; // 24小時(shí)
// 生成JWT令牌
public String generateToken(Integer userId, String role) {
Map<String, Object> claims = new HashMap<>();
claims.put("userId", userId);
claims.put("role", role);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
// 解析JWT令牌
public Claims parseToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
}
// 驗(yàn)證JWT令牌
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
}
JWT攔截器實(shí)現(xiàn)
創(chuàng)建攔截器來(lái)驗(yàn)證請(qǐng)求中的JWT令牌:
package com.bookstore.config;
import com.bookstore.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class JwtInterceptor implements HandlerInterceptor {
@Autowired
private JwtUtil jwtUtil;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 放行OPTIONS請(qǐng)求
if ("OPTIONS".equals(request.getMethod())) {
return true;
}
// 從請(qǐng)求頭獲取token
String token = request.getHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
token = token.substring(7);
if (jwtUtil.validateToken(token)) {
Claims claims = jwtUtil.parseToken(token);
// 將用戶信息存入request屬性中
request.setAttribute("userId", claims.get("userId"));
request.setAttribute("role", claims.get("role"));
return true;
}
}
response.setStatus(401);
return false;
}
}
MVC配置
配置攔截器并設(shè)置攔截路徑:
package com.bookstore.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private JwtInterceptor jwtInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor)
.addPathPatterns("/**") // 攔截所有路徑
.excludePathPatterns( // 排除路徑
"/login",
"/register",
"/swagger-resources/**",
"/webjars/**",
"/v3/api-docs/**",
"/swagger-ui.html/**",
"/error",
"/favicon.ico",
"doc.html",
"/logout",
"/static/**",
"/carousel/list",
"/book/new",
"/v2/api-docs"
);
}
}
使用示例
登錄時(shí)生成令牌
在登錄成功后生成JWT令牌并返回給客戶端:
String token = jwtUtil.generateToken(foundUser.getId(), foundUser.getRole());
基礎(chǔ)控制器
創(chuàng)建基礎(chǔ)控制器方便獲取已認(rèn)證的用戶信息:
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
public class BaseController {
@Autowired
protected HttpServletRequest request;
// 獲取當(dāng)前用戶ID
protected Integer getCurrentUserId() {
return (Integer) request.getAttribute("userId");
}
// 獲取當(dāng)前用戶角色
protected String getCurrentUserRole() {
return (String) request.getAttribute("role");
}
// 檢查是否是管理員
protected boolean isAdmin() {
return "admin".equals(getCurrentUserRole());
}
// 檢查是否是普通用戶
protected boolean isUser() {
return "user".equals(getCurrentUserRole());
}
}
其他控制器可以繼承BaseController來(lái)方便地獲取用戶信息:
@RestController
@RequestMapping("/api/books")
public class BookController extends BaseController {
@GetMapping("/{id}")
public ResponseEntity<Book> getBook(@PathVariable Integer id) {
if (isAdmin()) {
// 管理員特有邏輯
}
// 其他邏輯...
}
}
總結(jié)
- JWT工具類:封裝了令牌的生成、解析和驗(yàn)證邏輯
- 攔截器:自動(dòng)驗(yàn)證請(qǐng)求中的JWT令牌并提取用戶信息
- MVC配置:靈活配置需要攔截和放行的路徑
- 基礎(chǔ)控制器:提供便捷的方法獲取當(dāng)前用戶信息
這種實(shí)現(xiàn)方式具有以下優(yōu)點(diǎn):
- 無(wú)狀態(tài)認(rèn)證,服務(wù)端不需要存儲(chǔ)會(huì)話信息
- 跨域支持良好
- 可以方便地?cái)y帶用戶信息
- 適合分布式系統(tǒng)
在實(shí)際項(xiàng)目中,可以根據(jù)需求調(diào)整令牌的有效期、密鑰的存儲(chǔ)方式(如從配置中心獲取)以及更精細(xì)的權(quán)限控制邏輯。
到此這篇關(guān)于Spring Boot整合JWT實(shí)現(xiàn)認(rèn)證與授權(quán)的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)Spring Boot JWT認(rèn)證與授權(quán)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 詳解Spring Boot實(shí)戰(zhàn)之Filter實(shí)現(xiàn)使用JWT進(jìn)行接口認(rèn)證
- Vue+Jwt+SpringBoot+Ldap完成登錄認(rèn)證的示例代碼
- Springboot集成Spring Security實(shí)現(xiàn)JWT認(rèn)證的步驟詳解
- SpringBoot整合SpringSecurity和JWT和Redis實(shí)現(xiàn)統(tǒng)一鑒權(quán)認(rèn)證
- SpringBoot使用Jwt處理跨域認(rèn)證問(wèn)題的教程詳解
- 詳解SpringBoot如何使用JWT實(shí)現(xiàn)身份認(rèn)證和授權(quán)
- 利用Springboot實(shí)現(xiàn)Jwt認(rèn)證的示例代碼
- springboot+jwt實(shí)現(xiàn)token登陸權(quán)限認(rèn)證的實(shí)現(xiàn)
- SpringBoot整合SpringSecurity實(shí)現(xiàn)JWT認(rèn)證的項(xiàng)目實(shí)踐
相關(guān)文章
基于spring+quartz的分布式定時(shí)任務(wù)框架實(shí)現(xiàn)
在Spring中的定時(shí)任務(wù)功能,最好的辦法當(dāng)然是使用Quartz來(lái)實(shí)現(xiàn)。這篇文章主要介紹了基于spring+quartz的分布式定時(shí)任務(wù)框架實(shí)現(xiàn),有興趣的可以了解一下。2017-01-01
SpringBoot使用Thymeleaf模板引擎訪問(wèn)靜態(tài)html的過(guò)程
這篇文章主要介紹了SpringBoot使用Thymeleaf模板引擎訪問(wèn)靜態(tài)html的過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
Java 通過(guò)JDBC連接Mysql數(shù)據(jù)庫(kù)
本文給大家詳細(xì)介紹了java如何使用JDBC連接Mysql的方法以及驅(qū)動(dòng)包的安裝,最后給大家附上了java通過(guò)JDBC連接其他各種數(shù)據(jù)庫(kù)的方法,有需要的小伙伴可以參考下。2015-11-11
Spring Security中集成JWT的完整實(shí)戰(zhàn)指南
本文深入探討了現(xiàn)代Web應(yīng)用中的認(rèn)證授權(quán)方案,對(duì)比分析了JWT、Session-Cookie、OAuth2/OIDC、SAML 2.0等主流方案的優(yōu)缺點(diǎn)及適用場(chǎng)景,感興趣的小伙伴可以了解下2026-05-05
Java單機(jī)環(huán)境實(shí)現(xiàn)定時(shí)任務(wù)技術(shù)
這篇文章主要介紹了Java單機(jī)環(huán)境實(shí)現(xiàn)定時(shí)任務(wù)技術(shù),文章內(nèi)容介紹詳細(xì),具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-04-04
Spring Security單項(xiàng)目權(quán)限設(shè)計(jì)過(guò)程解析
這篇文章主要介紹了Spring Security單項(xiàng)目權(quán)限設(shè)計(jì)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
解決CentOS7中運(yùn)行jar包報(bào)錯(cuò):xxx(Permission?denied)
在實(shí)際工作我們經(jīng)常會(huì)在linux上運(yùn)行Spring boot編寫(xiě)的微服務(wù)程序,下面這篇文章主要給大家介紹了關(guān)于如何解決CentOS7中運(yùn)行jar包報(bào)錯(cuò):xxx(Permission?denied)的相關(guān)資料,需要的朋友可以參考下2024-02-02
純Java實(shí)現(xiàn)數(shù)字證書(shū)生成簽名的簡(jiǎn)單實(shí)例
下面小編就為大家?guī)?lái)一篇純Java實(shí)現(xiàn)數(shù)字證書(shū)生成簽名的簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08

