springboot+jwt實(shí)現(xiàn)token登陸權(quán)限認(rèn)證的實(shí)現(xiàn)
一 前言
此篇文章的內(nèi)容也是學(xué)習(xí)不久,終于到周末有時(shí)間碼一篇文章分享知識(shí)追尋者的粉絲們,學(xué)完本篇文章,讀者將對(duì)token類的登陸認(rèn)證流程有個(gè)全面的了解,可以動(dòng)態(tài)搭建自己的登陸認(rèn)證過程;對(duì)小項(xiàng)目而已是個(gè)輕量級(jí)的認(rèn)證機(jī)制,符合開發(fā)需求;
二 jwt實(shí)現(xiàn)登陸認(rèn)證流程
- 用戶使用賬號(hào)和面發(fā)出post請(qǐng)求
- 服務(wù)器接受到請(qǐng)求后使用私鑰創(chuàng)建一個(gè)jwt,這邊會(huì)生成token
- 服務(wù)器返回這個(gè)jwt給瀏覽器
- 瀏覽器需要將帶有token的jwt放入請(qǐng)求頭
- 每次手到客戶端請(qǐng)求,服務(wù)器驗(yàn)證該jwt的token
- 驗(yàn)證成功返回響應(yīng)的資源給瀏覽器。否則異常處理
三 相關(guān)介紹jwt
3.1jwt 組成
JWT的token由三段信息構(gòu)成的,將這三段信息文本用.連接一起就構(gòu)成了JWT字符串;
- Header 頭部(包含了令牌的元數(shù)據(jù),并且包含簽名和或加密算法的類型)
- Payload 負(fù)載
- Signature 簽名/簽證
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1ODI4OTc4NDUsInVzZXJuYW1lIjoienN6eHoifQ.vyiExkFWCCmQA3PFYL0jJfIiYGWubngqB0WcgmtHOxg
3.2 jwt優(yōu)點(diǎn)
- 簡(jiǎn)潔(Compact): 可以通過URL,POST參數(shù)或者在HTTP header發(fā)送,數(shù)據(jù)量小,傳輸速度快
- 自包含(Self-contained):負(fù)載中包含了所有用戶所需要的信息,避免多次查詢數(shù)據(jù)庫
- .因?yàn)門oken是以JSON加密的形式保存在客戶端的,所以JWT是跨語言支持;
- 不需要在服務(wù)端保存會(huì)話信息,適用于分布式與微服務(wù);
四 jwt用戶登陸發(fā)放token
4.1 pom.xml
項(xiàng)目構(gòu)件如下
- springboot 2.1;
- jwt 3.4.0;
- maven 3.5
- jdk1.8
- postman接口測(cè)試
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies>
4.2jwt工具類
jwt工具類中有三個(gè)方法,分別是生成數(shù)字簽名用于用戶首次登陸時(shí)發(fā)送jwt給客戶端;其次是校驗(yàn)方法,用于攔截器攔截所有規(guī)則內(nèi)的url,每個(gè)請(qǐng)求都必須帶有服務(wù)器發(fā)送的jwt,經(jīng)過驗(yàn)證后才放行請(qǐng)求;最后一個(gè)獲得用戶名的方法用于查詢密鑰,在驗(yàn)證jwt時(shí)作為參數(shù)傳入;
/* *
* @Author lsc
* <p> JWT工具類 </p>
* @Param
* @Return
*/
public class JwtUtil {
// Token過期時(shí)間30分鐘
public static final long EXPIRE_TIME = 30 * 60 * 1000;
/* *
* @Author lsc
* <p> 校驗(yàn)token是否正確 </p>
* @Param token
* @Param username
* @Param secret
* @Return boolean
*/
public static boolean verify(String token, String username, String secret) {
try {
// 設(shè)置加密算法
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm)
.withClaim("username", username)
.build();
// 效驗(yàn)TOKEN
DecodedJWT jwt = verifier.verify(token);
return true;
} catch (Exception exception) {
return false;
}
}
/* *
* @Author lsc
* <p>生成簽名,30min后過期 </p>
* @Param [username, secret]
* @Return java.lang.String
*/
public static String sign(String username, String secret) {
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
Algorithm algorithm = Algorithm.HMAC256(secret);
// 附帶username信息
return JWT.create()
.withClaim("username", username)
.withExpiresAt(date)
.sign(algorithm);
}
/* *
* @Author lsc
* <p> 獲得用戶名 </p>
* @Param [request]
* @Return java.lang.String
*/
public static String getUserNameByToken(HttpServletRequest request) {
String token = request.getHeader("token");
DecodedJWT jwt = JWT.decode(token);
return jwt.getClaim("username")
.asString();
}
}
4.3 用戶實(shí)體
實(shí)體中包含用戶名,和密碼,一切從簡(jiǎn);
/**
* @Author lsc
* <p> </p>
*/
@Data
public class SysUser {
private String username;
private String password;
}
4.4Controller
表現(xiàn)層代碼用戶用戶登陸認(rèn)證,認(rèn)證成功后發(fā)放token給客戶端;
/**
* @Author lsc
* <p> </p>
*/
@RestController
public class SysUserController {
@PostMapping(value = "/login")
public Map<String, Object> login(@RequestBody SysUser sysUser){
Map<String, Object> map = new HashMap<>();
String username = sysUser.getUsername();
String password = sysUser.getPassword();
// 省略 賬號(hào)密碼驗(yàn)證
// 驗(yàn)證成功后發(fā)送token
String token = JwtUtil.sign(username,password);
if (token != null){
map.put("code", "200");
map.put("message","認(rèn)證成功");
map.put("token", token);
return map;
}
map.put("code", "403");
map.put("message","認(rèn)證失敗");
return map;
}
}
4.5 測(cè)試
測(cè)試url http://localhost:8080/login
postman post請(qǐng)求測(cè)試參數(shù)如下
{
"username": "zszxz",
"password": "zszxz"
}
返回內(nèi)容如下
{
"code": "200",
"message": "認(rèn)證成功",
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1ODI4OTc4NDUsInVzZXJuYW1lIjoienN6eHoifQ.vyiExkFWCCmQA3PFYL0jJfIiYGWubngqB0WcgmtHOxg"
}
五 jwt登陸攔截認(rèn)證
基于前面已經(jīng)實(shí)現(xiàn)jwt登錄認(rèn)證后發(fā)放token給客戶端;本節(jié)內(nèi)容就是將token放入請(qǐng)求頭中發(fā)送請(qǐng)求給服務(wù)器;服務(wù)器使用攔截器攔截請(qǐng)求對(duì)token進(jìn)行驗(yàn)證;驗(yàn)證成功請(qǐng)求通過,否則請(qǐng)求資源失??;
5.1自定義攔截器
自定義攔截器JwtInterceptor,實(shí)現(xiàn)HandlerInterceptor接口,每次請(qǐng)求到達(dá)之前都會(huì)驗(yàn)證token是否有效;
/**
* @Author lsc
* <p>token驗(yàn)證攔截器 </p>
*/
@Component
public class JwtInterceptor implements HandlerInterceptor {
@Autowired
SysUserService sysUserService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 從 http 請(qǐng)求頭中取出 token
String token = request.getHeader("token");
// 如果不是映射到方法直接通過
if(!(handler instanceof HandlerMethod)){
return true;
}
if (token != null){
String username = JwtUtil.getUserNameByToken(request);
// 這邊拿到的 用戶名 應(yīng)該去數(shù)據(jù)庫查詢獲得密碼,簡(jiǎn)略,步驟在service直接獲取密碼
boolean result = JwtUtil.verify(token,username,sysUserService.getPassword());
if(result){
System.out.println("通過攔截器");
return true;
}
}
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
5.2 service
/**
* @Author lsc
* <p> 模擬查詢數(shù)據(jù)庫獲得賬號(hào)密碼 </p>
*/
@Service
public class SysUserService {
public String getPassword(){
return "zszxz";
}
}
5.3攔截器配置
攔截器配置中主要定義攔截請(qǐng)求規(guī)則,將攔截器注入WebMvcConfigurer;cors跨域處理;
/* *
* @Author lsc
* <p>攔截器配置 </p>
* @Param
* @Return
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
/* *
* @Author lsc
* <p> 設(shè)置攔截路徑 </p>
* @Param [registry]
* @Return void
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authenticationInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/login");
}
/* *
* @Author lsc
* <p> 將攔截器注入context </p>
* @Param []
* @Return com.zszxz.jwt.interceptor.JwtInterceptor
*/
@Bean
public JwtInterceptor authenticationInterceptor() {
return new JwtInterceptor();
}
/* *
* @Author lsc
* <p>跨域支持 </p>
* @Param [registry]
* @Return void
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH", "OPTIONS", "HEAD")
.maxAge(3600 * 24);
}
}
5.4Controller
表現(xiàn)層接口用于攔截親求測(cè)試
/**
* @Author lsc
* <p> </p>
*/
@RestController
public class TestController {
@GetMapping(value = "/api/test")
public String get(){
return "zszxz";
}
}
5.5 測(cè)試
測(cè)試url http://localhost:8080/api/test
發(fā)送get請(qǐng)求給服務(wù)器,帶有請(qǐng)求頭,key為token,value為用戶首次登陸時(shí)返回的token串;
測(cè)試返回內(nèi)容如下
zszxz
六 官網(wǎng)鏈接
到此這篇關(guān)于springboot+jwt實(shí)現(xiàn)token登陸權(quán)限認(rèn)證的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)springboot jwt token登陸權(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)證問題的教程詳解
- 詳解SpringBoot如何使用JWT實(shí)現(xiàn)身份認(rèn)證和授權(quán)
- 利用Springboot實(shí)現(xiàn)Jwt認(rèn)證的示例代碼
- SpringBoot整合SpringSecurity實(shí)現(xiàn)JWT認(rèn)證的項(xiàng)目實(shí)踐
- Spring Boot整合JWT實(shí)現(xiàn)認(rèn)證與授權(quán)的項(xiàng)目實(shí)踐
相關(guān)文章
SpringBoot創(chuàng)建maven多模塊項(xiàng)目實(shí)戰(zhàn)代碼
本篇文章主要介紹了SpringBoot創(chuàng)建maven多模塊項(xiàng)目實(shí)戰(zhàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09
java?11新特性HttpClient主要組件及發(fā)送請(qǐng)求示例詳解
這篇文章主要為大家介紹了java?11新特性HttpClient主要組件及發(fā)送請(qǐng)求示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
使用easyexcel導(dǎo)出的excel文件,使用poi讀取時(shí)異常處理方案
這篇文章主要介紹了使用easyexcel導(dǎo)出的excel文件,使用poi讀取時(shí)異常處理方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Spring Boot與RabbitMQ結(jié)合實(shí)現(xiàn)延遲隊(duì)列的示例
本篇文章主要介紹了Spring Boot與RabbitMQ結(jié)合實(shí)現(xiàn)延遲隊(duì)列的示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
SpringBoot 嵌入式web容器的啟動(dòng)原理詳解
這篇文章主要介紹了SpringBoot 嵌入式web容器的啟動(dòng)原理詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2021-11-11
Java最常用的6個(gè)簡(jiǎn)單的計(jì)算題
本篇文章給大家整理的在JAVA中最常用到的簡(jiǎn)單的計(jì)算題,對(duì)此有興趣的朋友可以測(cè)試參考下。2018-02-02

