SpringBoot與JWT整合方式
SpringBoot與JWT整合
JWT的結(jié)構(gòu)
Header(頭):包含令牌的類型與使用的簽名算法,它會使用Base64進(jìn)行編碼
{ "alg": "HS265", "typ": "JWT" }
Payload(有效負(fù)載): 包含聲明(有關(guān)用戶實(shí)體和其他數(shù)據(jù)的聲明),使用Base64進(jìn)行編碼Base64是一種可逆的編碼,因此不要在負(fù)載里存入敏感數(shù)據(jù)!
{ "id": "1", "name": "BLU", "admin": true }
Signature(簽名):使用編碼后的header和payload以及一個指定密鑰,然后使用header中指定的算法(HS265)進(jìn)行簽名.
簽名的作用是保證JWT沒有被篡改過
JWT的使用測試
- 依賴:
<dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.4.0</version> </dependency>
- 測試:
@Test void getToken() { //HashMap<String,Object> map = new HashMap<String, Object>(); Calendar instance = Calendar.getInstance(); instance.add(Calendar.SECOND, 60); String token = JWT.create() //.withHeader(map) //設(shè)置Payload .withClaim("userId", 10) .withClaim("username", "BLU") //設(shè)置token過期時間(60s) .withExpiresAt(instance.getTime()) //設(shè)置簽名 .sign(Algorithm.HMAC256("!@#$%^&*")); System.out.println(token); }
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MDA3NDA2MTUsInVzZXJJZCI6MTAsInVzZXJuYW1lIjoiQkxVIn0.0re-tA4dQm4blGhn1DvpnUl7Lrz_EWXwn8LfRbWQXCU
@Test void TokenVerify() { //創(chuàng)建驗(yàn)證對象 JWTVerifier verifier = JWT.require(Algorithm.HMAC256("!@#$%^&*")).build(); DecodedJWT verify = verifier.verify("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MDA3NDA2MTUsInVzZXJJZCI6MTAsInVzZXJuYW1lIjoiQkxVIn0.0re-tA4dQm4blGhn1DvpnUl7Lrz_EWXwn8LfRbWQXCU"); System.out.println(verify.getClaim("userId").asInt()); System.out.println(verify.getClaims().get("username").asString()); System.out.println("過期時間:"+verify.getExpiresAt()); }
10
BLU
過期時間:Tue Sep 22 10:10:15 CST 2020
SpringBoot與JWT整合
- 依賴
<dependencies> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.22</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
- 配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/jwt?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8 spring.datasource.username=root spring.datasource.password=123456 mybatis.type-aliases-package=com.blu.entity mybatis.mapper-locations=classpath:mapper/*.xml logging.level.com.blu.dao=debug
- 數(shù)據(jù)庫user表:
- 實(shí)體類:
package com.blu.entity; import lombok.Data; import lombok.experimental.Accessors; @Data @Accessors(chain=true) public class User { private String id; private String name; private String password; }
- UserDao:
package com.blu.dao; import org.apache.ibatis.annotations.Mapper; import com.blu.entity.User; @Mapper public interface UserDao { User login(User user); }
- UserMapper:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.blu.dao.UserDao"> <select id="login" parameterType="User" resultType="User"> select * from user where name= #{name} and password= #{password} </select> </mapper>
- UserService:
package com.blu.service; import com.blu.entity.User; public interface UserService { User login(User user); }
- UserServiceImpl:
package com.blu.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.blu.dao.UserDao; import com.blu.entity.User; import com.blu.service.UserService; @Service public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Override public User login(User user) { User userDB = userDao.login(user); if(userDB!=null) { return userDB; } throw new RuntimeException("認(rèn)證失?。?); } }
- JWT的工具類封裝:
package com.blu.utils; import java.util.Calendar; import java.util.Map; import com.auth0.jwt.JWT; import com.auth0.jwt.JWTCreator; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.DecodedJWT; public class JWTUtils { private static final String SIGN= "!@#$%^&*123456789"; /** * 生成Token */ public static String getToken(Map<String,String> map) { Calendar instance = Calendar.getInstance(); instance.add(Calendar.DATE, 7); //創(chuàng)建JWTBuilder JWTCreator.Builder builder = JWT.create(); //設(shè)置payload map.forEach((k,v)->{ builder.withClaim(k, v); }); //設(shè)置過期時間和簽名,生成token String token = builder.withExpiresAt(instance.getTime()) .sign(Algorithm.HMAC256(SIGN)); return token; } /** * 驗(yàn)證token */ public static void TokenVerify(String token) { JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token); } /** * 獲取token信息 */ public static DecodedJWT getTokenInfo(String token) { DecodedJWT verify = JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token); return verify; } }
- JWTInterceptor 攔截器
package com.blu.interceptors; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import com.auth0.jwt.exceptions.AlgorithmMismatchException; import com.auth0.jwt.exceptions.SignatureVerificationException; import com.auth0.jwt.exceptions.TokenExpiredException; import com.blu.utils.JWTUtils; import com.fasterxml.jackson.databind.ObjectMapper; public class JWTInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //獲取請求頭中的token String token = request.getHeader("token"); Map<String,Object> map = new HashMap<String, Object>(); try { JWTUtils.TokenVerify(token); //放行請求 return true; } catch (SignatureVerificationException e) { map.put("msg", "無效簽名"); e.printStackTrace(); } catch (TokenExpiredException e) { map.put("msg", "token已過期"); e.printStackTrace(); } catch (AlgorithmMismatchException e) { map.put("msg", "算法不一致"); e.printStackTrace(); } catch (Exception e) { map.put("msg", "token無效"); e.printStackTrace(); } map.put("state",false); //使用jackson將map轉(zhuǎn)為json String json = new ObjectMapper().writeValueAsString(map); response.setContentType("application/json;charset=UTF-8"); response.getWriter().print(json); return false; } }
- InterceptorConfig 配置類
package com.blu.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import com.blu.interceptors.JWTInterceptor; @Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new JWTInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/user/login"); } }
- UserController
package com.blu.controller; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import com.auth0.jwt.exceptions.AlgorithmMismatchException; import com.auth0.jwt.exceptions.SignatureVerificationException; import com.auth0.jwt.exceptions.TokenExpiredException; import com.auth0.jwt.interfaces.DecodedJWT; import com.blu.entity.User; import com.blu.service.UserService; import com.blu.utils.JWTUtils; import lombok.extern.slf4j.Slf4j; @RestController @Slf4j public class UserController { @Autowired private UserService userService; @GetMapping("/user/login") public Map<String,Object> login(User user){ log.info("用戶名:[{}]",user.getName()); log.info("密碼:[{}]",user.getPassword()); Map<String,Object> map = new HashMap<String, Object>(); try { User userDB = userService.login(user); Map<String,String> payload = new HashMap<String, String>(); payload.put("id", userDB.getId()); payload.put("name", userDB.getName()); String token = JWTUtils.getToken(payload); map.put("state",true); map.put("msg","認(rèn)證成功"); map.put("token", token); } catch (Exception e) { map.put("state",false); map.put("msg",e.getMessage()); } return map; } @PostMapping("/user/test") public Map<String,Object> test(HttpServletRequest request){ String token = request.getHeader("token"); DecodedJWT tokenInfo = JWTUtils.getTokenInfo(token); log.info("用戶id:[{}]",tokenInfo.getClaim("id").asString()); log.info("用戶名:[{}]",tokenInfo.getClaim("name").asString()); Map<String,Object> map = new HashMap<String, Object>(); map.put("state", true); map.put("msg","請求成功"); return map; } }
- 測試
登錄獲取token:
測試錯誤的token:
測試正確的token:
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot項(xiàng)目POM文件的使用小結(jié)
本文主要詳細(xì)介紹了Maven中SpringBoot項(xiàng)目的POM文件配置,包括項(xiàng)目的依賴和插件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-11-11Spring Cloud Feign文件傳輸?shù)氖纠a
微服務(wù)中通常使用 Feign 作為服務(wù)消費(fèi)者,那么如何使用 Feign 接口傳輸文件呢?這篇文章主要介紹了Spring Cloud Feign文件傳輸?shù)氖纠a,感興趣的小伙伴們可以參考一下2018-06-06intellij idea如何配置網(wǎng)絡(luò)代理
intellij idea所在的這臺電腦本身上不了網(wǎng),要通過代理上網(wǎng),那么intellij idea怎么設(shè)置代理上網(wǎng)呢?今天通過本文給大家分享intellij idea如何配置網(wǎng)絡(luò)代理,感興趣的朋友一起看看吧2023-10-10mybatis中的mapper.xml使用循環(huán)語句
這篇文章主要介紹了mybatis中的mapper.xml使用循環(huán)語句,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02Java實(shí)現(xiàn)利用廣度優(yōu)先遍歷(BFS)計算最短路徑的方法
這篇文章主要介紹了Java實(shí)現(xiàn)利用廣度優(yōu)先遍歷(BFS)計算最短路徑的方法,實(shí)例分析了廣度優(yōu)先遍歷算法的原理與使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-04-04