實現思路:
- 用戶登錄請求登錄接口時,驗證用戶名密碼等,驗證成功會返回給前端一個token,這個token就是之后鑒權的唯一憑證。
- 后台可能將token存儲在redis或者數據庫中。
- 之后前端的請求,需要在header中攜帶token,后端取出token去redis或者數據庫中進行驗證,如果驗證通過則放行,如果不通過則拒絕操作。
當然,如上的說法只是簡單的實現,實質上還有很多需要優化的地方。
可以參考:https://blog.csdn.net/kkkun_joe/article/details/81878231
https://www.javamall.com.cn/blog/archives/642
具體實現方式
1、添加依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.jwt.token</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、生成簽名方法
/**
* 生成簽名
*/
public String sign(String userName,String passWord){
Date date=new Date(System.currentTimeMillis()+3600);
//設置私鑰和加密算法
Algorithm algorithm=Algorithm.HMAC256("sadfsfsf3r3r545dfdfasas");
//設置頭部信息
Map<String,Object> header=new HashMap<>();
header.put("typ","JWT");
header.put("alg","HS256");
String token = JWT.create().withHeader(header).withClaim("userName", userName)
.withClaim("passWord", passWord).withExpiresAt(date).sign(algorithm);
return token;
}
3、解碼,通過token獲取用戶名
/**
* 通過token獲取用戶
* @param token
*/
@GetMapping("/user/{token}")
public void getUserName(@PathVariable("token") String token){
String userName = JWT.decode(token).getClaim("userName").asString();
System.out.println(userName);
}
4、增加攔截器
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
private LoginController loginController;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("token");
if(StringUtils.isEmpty(token)){
throw new Exception("token不能為空");
}
Boolean verify = null;
try {
LoginController loginController=new LoginController();
verify = loginController.verify(token);
if(verify){
return true;
}else {
return false;
}
} catch (Exception e) {
return false;
}
}
}
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/login")
;
}
}
5、測試
@GetMapping("/login")
public String login(){
//模擬用戶名和密碼
String userName="admin";
String passWord="admin";
String token = sign(userName, passWord);
return token;
}

