SpringBoot整合Mybatis-Plus、Jwt實現(xiàn)登錄token設置
Spring Boot整合Mybatis-plus實現(xiàn)登錄常常需要使用JWT來生成用戶的token并設置用戶權限的攔截器。本文將為您介紹JWT的核心講解、示例代碼和使用規(guī)范,以及如何實現(xiàn)token的生成和攔截器的使用。
一、JWT的核心講解
JWT(JSON Web Token)是一種基于JSON的,用于在網(wǎng)絡上安全傳輸信息的開放標準(RFC 7519)。JWT有三個部分組成,分別是Header(頭部)、Payload(載荷)和Signature(簽名)。
- Header
Header部分通常由兩部分組成:令牌的類型和使用的加密算法。例如:
{ "alg": "HS256", "typ": "JWT" }
其中,“alg” 參數(shù)表示簽名的算法(例如HS256),“typ” 參數(shù)表示令牌的類型(例如JWT)。
- Payload
Payload是JWT的核心部分,其中包含了需要傳輸?shù)男畔ⅰJ纠?/p>
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
其中,“sub” 參數(shù)表示主題(Subject),“name” 參數(shù)表示名稱,“iat” 參數(shù)表示令牌的簽發(fā)時間。
- Signature
Signature部分是JWT的第三部分,它由頭部和載荷組合后進行簽名而產(chǎn)生。
二、JWT 的使用規(guī)范
生成 JWT
使用 Java JWT 庫生成 JWT,示例代碼如下:
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jws; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.security.Keys; import javax.crypto.SecretKey; import java.util.Date; public class JwtUtil { private static final byte[] SECRET_KEY = "secretkeyhere".getBytes(); private static final long EXPIRATION_TIME = 3600000L; // 1 hour public static String createJwt(String subject, String scopes) { SecretKey key = Keys.hmacShaKeyFor(SECRET_KEY); Date now = new Date(); Date expiration = new Date(now.getTime() + EXPIRATION_TIME); String jwt = Jwts.builder() .setIssuer("demo") .setSubject(subject) .setExpiration(expiration) .claim("scopes", scopes) .setIssuedAt(now) .signWith(key, SignatureAlgorithm.HS512) .compact(); return jwt; } public static Jws<Claims> parseJwt(String jwt) { SecretKey key = Keys.hmacShaKeyFor(SECRET_KEY); Jws<Claims> jws = Jwts.parserBuilder() .setSigningKey(key) .build() .parseClaimsJws(jwt); return jws; } }
其中,SECRET_KEY 是用于簽名的密鑰,建議使用足夠隨機的字符串或 byte 數(shù)組;EXPIRATION_TIME 是過期時間,設置為 1 小時;createJwt() 方法會創(chuàng)建 JWT,并將用戶標識(subject)和權限(scopes)作為載荷;parseJwt() 方法用于解析 JWT。
解析 JWT
解析 JWT 部分和生成 JWT 略有不同。示例代碼如下:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @Component public class JwtAuthenticationFilter extends OncePerRequestFilter { private static final List<String> ALLOWED_URIS = Arrays.asList("/login"); @Autowired private JwtProperties jwtProperties; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String jwt = request.getHeader("Authorization"); if (jwt != null) { jwt = jwt.replace("Bearer ", ""); try { Jwts.parserBuilder().setSigningKey(jwtProperties.getSecret()).build().parseClaimsJws(jwt); String[] scopes = ((String)Jwts.parserBuilder().setSigningKey(jwtProperties.getSecret().parseClaimsJws(jwt).getBody().get("scopes")).split(","); Set<String> allowedScopes = Arrays.stream(scopes) .map(String::trim) .collect(Collectors.toSet()); String uri = request.getRequestURI(); if (!ALLOWED_URIS.contains(uri)) { if (!allowedScopes.contains("all") && !allowedScopes.contains(uri)) { response.sendError(HttpStatus.FORBIDDEN.value()); return; } } } catch (Exception e) { response.sendError(HttpStatus.UNAUTHORIZED.value()); return; } } filterChain.doFilter(request, response); } }
這段代碼定義了一個JwtAuthenticationFilter,它會在每次請求進入 Controller 之前進行攔截,解析 JWT 并根據(jù)用戶權限進行攔截。ALLOWED_URIS 定義了不需要 JWT 驗證的 URL,比如登錄接口。jwtProperties 用于讀取一些 JWT 相關的配置,比如密鑰(secret)等。
三、Mybatis-plus 使用 JWT 實現(xiàn)登錄
在 Mybatis-plus 中使用 JWT 時,我們需要在登錄成功之后生成 JWT,并將其返回給客戶端??蛻舳嗽谝院蟮恼埱笾卸紩?JWT,我們需要在攔截器中解析 JWT 并進行權限校驗。
首先,在 pom.xml 中添加相關依賴:
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.2</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency>
然后,我們需要創(chuàng)建一個 JwtUtil 工具類,用于生成和解析 JWT:
import io.jsonwebtoken.Claims; import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.impl.DefaultClaims; import java.util.Date; public class JwtUtil { private static final String SECRET = "secretkey"; public static String generateToken(String username, Long expiration) { Date now = new Date(); Date expireTime = new Date(now.getTime() + expiration * 1000); JwtBuilder builder = Jwts.builder() .setId(username) .setIssuedAt(now) .setExpiration(expireTime) .signWith(SignatureAlgorithm.HS256, SECRET); return builder.compact(); } public static Claims parseToken(String token) { return Jwts.parser() .setSigningKey(SECRET) .parseClaimsJws(token) .getBody(); } }
在登錄成功之后,我們需要調(diào)用 JwtUtil.generateToken() 方法生成 JWT,并將其返回給客戶端。客戶端在以后的請求中都會帶上 JWT,我們需要在攔截器中解析 JWT 并進行權限校驗:
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 JwtIntercepter implements HandlerInterceptor { @Autowired private JwtProperties jwtProperties; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String authorization = request.getHeader("Authorization"); if (authorization != null && authorization.startsWith("Bearer ")) { String token = authorization.substring(7); try { Claims claims = JwtUtil.parseToken(token); request.setAttribute("username", claims.getSubject()); return true; } catch (Exception e) { response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage()); return false; } } else { response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "No token provided in the request header"); return false; } } }
在攔截器中,我們通過 request.setAttribute() 方法將解析出來的用戶信息保存在 Request 中,后續(xù)可以通過 Request 獲取到用戶信息。在攔截器中,我們也可以實現(xiàn)權限校驗的邏輯。如果校驗失敗,我們可以通過 response.sendError() 方法返回403 或 401 狀態(tài)碼,告知客戶端請求被拒絕或未經(jīng)授權。
最后,定義一個 WebMvcConfigurerAdapter,將 JwtIntercepter 注冊為攔截器:
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 JwtIntercepter jwtIntercepter; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(jwtIntercepter) .addPathPatterns("/**") .excludePathPatterns("/login"); } }
在上述代碼中,我們通過 addPathPatterns() 方法設置需要攔截的 URL 路徑,并通過 excludePathPatterns() 方法排除不需要攔截的 URL 路徑。其中,“/login” 路徑為登錄接口,一般不需要攔截。
四、總結(jié)
本文介紹了在 Spring Boot 整合 Mybatis-plus 實現(xiàn)登錄時,使用 JWT 來生成用戶 Token 并設置用戶權限攔截器的方法。首先,我們需要了解 JWT 的核心框架和使用規(guī)范,并通過代碼實現(xiàn) JWT 的生成和解析。然后,我們在攔截器中實現(xiàn) JWT 的解析和權限校驗,最后通過 WebMvcConfigurerAdapter 將 JwtIntercepter 注冊為攔截器。、
到此這篇關于SpringBoot整合Mybatis-Plus、Jwt實現(xiàn)登錄token設置的文章就介紹到這了,更多相關SpringBoot 登錄token內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- SpringBoot整合Mybatis-Plus實現(xiàn)微信注冊登錄的示例代碼
- springboot3.2整合mybatis-plus詳細代碼示例
- SpringBoot3整合mybatis-plus的實現(xiàn)
- SpringBoot整合Mybatis-Plus+Druid實現(xiàn)多數(shù)據(jù)源配置功能
- SpringBoot?整合Mybatis-Plus并輸出SQL日志示例詳解
- SpringBoot中整合MyBatis-Plus-Join使用聯(lián)表查詢的實現(xiàn)
- SpringBoot整合Mybatis-Plus分頁失效的解決
- Spring Boot 中整合 MyBatis-Plus詳細步驟(最新推薦)
相關文章
解決spring 處理request.getInputStream()輸入流只能讀取一次問題
這篇文章主要介紹了解決spring 處理request.getInputStream()輸入流只能讀取一次問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09Java8 將一個List<T>轉(zhuǎn)為Map<String,T>的操作
這篇文章主要介紹了Java8 將一個List<T>轉(zhuǎn)為Map<String, T>的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02Spring Boot整合Elasticsearch實現(xiàn)全文搜索引擎案例解析
ElasticSearch作為基于Lucene的搜索服務器,既可以作為一個獨立的服務部署,也可以簽入Web應用中。SpringBoot作為Spring家族的全新框架,使得使用SpringBoot開發(fā)Spring應用變得非常簡單,在本案例中我們給大家介紹Spring Boot整合Elasticsearch實現(xiàn)全文搜索引擎2017-11-11Spring?IOC容器Bean注解創(chuàng)建對象組件掃描
這篇文章主要為大家介紹了Spring?IOC容器Bean注解創(chuàng)建對象組件掃描,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05java傳入時間戳返回LocalDateTime的實現(xiàn)方法
這篇文章主要介紹了java傳入時間戳返回LocalDateTime的實現(xiàn)方法,在Java中將時間戳轉(zhuǎn)換為LocalDateTime時需要注意時區(qū)問題,因為LocalDateTime不包含時區(qū)信息,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-11-11