實現思路:
- 用戶登錄請求登錄接口時,驗證用戶名密碼等,驗證成功會返回給前端一個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; }