SpringBoot整合Mybatis-Plus、Jwt實(shí)現(xiàn)登錄token設(shè)置
Spring Boot整合Mybatis-plus實(shí)現(xiàn)登錄常常需要使用JWT來生成用戶的token并設(shè)置用戶權(quán)限的攔截器。本文將為您介紹JWT的核心講解、示例代碼和使用規(guī)范,以及如何實(shí)現(xiàn)token的生成和攔截器的使用。
一、JWT的核心講解
JWT(JSON Web Token)是一種基于JSON的,用于在網(wǎng)絡(luò)上安全傳輸信息的開放標(biāo)準(zhǔn)(RFC 7519)。JWT有三個(gè)部分組成,分別是Header(頭部)、Payload(載荷)和Signature(簽名)。
- Header
Header部分通常由兩部分組成:令牌的類型和使用的加密算法。例如:
{ "alg": "HS256", "typ": "JWT" }
其中,“alg” 參數(shù)表示簽名的算法(例如HS256),“typ” 參數(shù)表示令牌的類型(例如JWT)。
- Payload
Payload是JWT的核心部分,其中包含了需要傳輸?shù)男畔?。示例?/p>
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
其中,“sub” 參數(shù)表示主題(Subject),“name” 參數(shù)表示名稱,“iat” 參數(shù)表示令牌的簽發(fā)時(shí)間。
- Signature
Signature部分是JWT的第三部分,它由頭部和載荷組合后進(jìn)行簽名而產(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 是用于簽名的密鑰,建議使用足夠隨機(jī)的字符串或 byte 數(shù)組;EXPIRATION_TIME 是過期時(shí)間,設(shè)置為 1 小時(shí);createJwt() 方法會(huì)創(chuàng)建 JWT,并將用戶標(biāo)識(shí)(subject)和權(quán)限(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); } }
這段代碼定義了一個(gè)JwtAuthenticationFilter,它會(huì)在每次請(qǐng)求進(jìn)入 Controller 之前進(jìn)行攔截,解析 JWT 并根據(jù)用戶權(quán)限進(jìn)行攔截。ALLOWED_URIS 定義了不需要 JWT 驗(yàn)證的 URL,比如登錄接口。jwtProperties 用于讀取一些 JWT 相關(guān)的配置,比如密鑰(secret)等。
三、Mybatis-plus 使用 JWT 實(shí)現(xiàn)登錄
在 Mybatis-plus 中使用 JWT 時(shí),我們需要在登錄成功之后生成 JWT,并將其返回給客戶端??蛻舳嗽谝院蟮恼?qǐng)求中都會(huì)帶上 JWT,我們需要在攔截器中解析 JWT 并進(jìn)行權(quán)限校驗(yàn)。
首先,在 pom.xml 中添加相關(guān)依賴:
<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>
然后,我們需要?jiǎng)?chuàng)建一個(gè) 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,并將其返回給客戶端??蛻舳嗽谝院蟮恼?qǐng)求中都會(huì)帶上 JWT,我們需要在攔截器中解析 JWT 并進(jìn)行權(quán)限校驗(yàn):
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 獲取到用戶信息。在攔截器中,我們也可以實(shí)現(xiàn)權(quán)限校驗(yàn)的邏輯。如果校驗(yàn)失敗,我們可以通過 response.sendError() 方法返回403 或 401 狀態(tài)碼,告知客戶端請(qǐng)求被拒絕或未經(jīng)授權(quán)。
最后,定義一個(gè) WebMvcConfigurerAdapter,將 JwtIntercepter 注冊(cè)為攔截器:
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() 方法設(shè)置需要攔截的 URL 路徑,并通過 excludePathPatterns() 方法排除不需要攔截的 URL 路徑。其中,“/login” 路徑為登錄接口,一般不需要攔截。
四、總結(jié)
本文介紹了在 Spring Boot 整合 Mybatis-plus 實(shí)現(xiàn)登錄時(shí),使用 JWT 來生成用戶 Token 并設(shè)置用戶權(quán)限攔截器的方法。首先,我們需要了解 JWT 的核心框架和使用規(guī)范,并通過代碼實(shí)現(xiàn) JWT 的生成和解析。然后,我們?cè)跀r截器中實(shí)現(xiàn) JWT 的解析和權(quán)限校驗(yàn),最后通過 WebMvcConfigurerAdapter 將 JwtIntercepter 注冊(cè)為攔截器。、
到此這篇關(guān)于SpringBoot整合Mybatis-Plus、Jwt實(shí)現(xiàn)登錄token設(shè)置的文章就介紹到這了,更多相關(guān)SpringBoot 登錄token內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot整合Mybatis-Plus實(shí)現(xiàn)微信注冊(cè)登錄的示例代碼
- springboot3.2整合mybatis-plus詳細(xì)代碼示例
- SpringBoot3整合mybatis-plus的實(shí)現(xiàn)
- SpringBoot整合Mybatis-Plus+Druid實(shí)現(xiàn)多數(shù)據(jù)源配置功能
- SpringBoot?整合Mybatis-Plus并輸出SQL日志示例詳解
- SpringBoot中整合MyBatis-Plus-Join使用聯(lián)表查詢的實(shí)現(xiàn)
- SpringBoot整合Mybatis-Plus分頁失效的解決
- Spring Boot 中整合 MyBatis-Plus詳細(xì)步驟(最新推薦)
相關(guān)文章
解決spring 處理request.getInputStream()輸入流只能讀取一次問題
這篇文章主要介紹了解決spring 處理request.getInputStream()輸入流只能讀取一次問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09Java8 將一個(gè)List<T>轉(zhuǎn)為Map<String,T>的操作
這篇文章主要介紹了Java8 將一個(gè)List<T>轉(zhuǎn)為Map<String, T>的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-02-02Spring Boot整合Elasticsearch實(shí)現(xiàn)全文搜索引擎案例解析
ElasticSearch作為基于Lucene的搜索服務(wù)器,既可以作為一個(gè)獨(dú)立的服務(wù)部署,也可以簽入Web應(yīng)用中。SpringBoot作為Spring家族的全新框架,使得使用SpringBoot開發(fā)Spring應(yīng)用變得非常簡(jiǎn)單,在本案例中我們給大家介紹Spring Boot整合Elasticsearch實(shí)現(xiàn)全文搜索引擎2017-11-11Spring?IOC容器Bean注解創(chuàng)建對(duì)象組件掃描
這篇文章主要為大家介紹了Spring?IOC容器Bean注解創(chuàng)建對(duì)象組件掃描,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05javaweb登錄驗(yàn)證碼的實(shí)現(xiàn)方法
這篇文章主要為大家詳細(xì)介紹了javaweb登錄驗(yàn)證碼的實(shí)現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11java傳入時(shí)間戳返回LocalDateTime的實(shí)現(xiàn)方法
這篇文章主要介紹了java傳入時(shí)間戳返回LocalDateTime的實(shí)現(xiàn)方法,在Java中將時(shí)間戳轉(zhuǎn)換為L(zhǎng)ocalDateTime時(shí)需要注意時(shí)區(qū)問題,因?yàn)長(zhǎng)ocalDateTime不包含時(shí)區(qū)信息,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-11-11