SpringCloud 框架基本模塊梳理 (二)
前言
本週更新的慢了一點,內容其實也不多。本篇接上篇來聊一下gateway的鑑權。這個詞比較晦澀,要是說成接口訪問權限校驗沒準顯得直白一些。
一、組件版本介紹
JWT 3.4 (新晉成員)
redis
二、核心步驟
(關於JWT的使用可以參閱各大論壇大佬的帖子,這裏就不過多的展開,只講方法,不擴展)
1、生成token
核心方法如下:
JWT.create().withAudience(user.getId().toString())
.sign(Algorithm.HMAC256(user.getPassword()))
2、校驗token
核心方法如下:
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
jwtVerifier.verify(token);
三、插話
要不順帶提一下redis的配置方式,以及簡單的使用。。。
jar包需要引入
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.3</version>
</dependency>
配置文件中需要聲明redis的服務地址(此處省略了redis的配置說明,找起來也容易的)
在默認的配置下,使用org.springframework.data.redis.core.RedisTemplate,主要方法有兩個:opsForCluster 和 delete ,兩者都接收一個String型的參數,前者做存,後者做刪除,當然還有個重要的過期時間設置 expire()方法,接收三個參數(Object-通常是redis裏的key值,timeOut-過期時間,TimeUnit.MILLISECONDS-時間單位)—不建議在併發下使用。
四、效果展示
本次就沒有效果展示了,貼一下token驗證的代碼吧。
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) {
String token = "";
Cookie[] cookies = httpServletRequest.getCookies();
if(cookies != null){
for (Cookie cookie : cookies){
if(cookie.getName().equals("Admin-Token")){
token = cookie.getValue();
}
}
}
// 如果不是映射到方法直接通過
if(!(object instanceof HandlerMethod)){
return true;
}
HandlerMethod handlerMethod=(HandlerMethod)object;
Method method=handlerMethod.getMethod();
//檢查是否有passtoken註釋,有則跳過認證
if (method.isAnnotationPresent(PassToken.class)) {
PassToken passToken = method.getAnnotation(PassToken.class);
if (passToken.required()) {
return true;
}
}
//檢查有沒有需要用戶權限的註解
if (method.isAnnotationPresent(UserLoginToken.class)) {
UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
if (userLoginToken.required()) {
// 執行認證
if (token == null) {
throw new RuntimeException("無token,請重新登錄");
}
// 獲取 token 中的 user id
Integer userId;
try {
userId = Integer.parseInt(JWT.decode(token).getAudience().get(0));
} catch (JWTDecodeException j) {
throw new RuntimeException("401");
}
TestUser user = userService.findUserById(userId);
if (user == null) {
throw new RuntimeException("用戶不存在,請重新登錄");
}
// 驗證 token
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
try {
jwtVerifier.verify(token);
} catch (JWTVerificationException e) {
throw new RuntimeException("401");
}
return true;
}
}
return false;
}
這就是jwt使用最重要的部分了,實際應用中,可以將獲取的token存放至redis中,在過期時間內重複的校驗都是OK的。
五、結語
(這一週有點懶散,見諒!)