過(guò)濾器的功能是檢驗(yàn)經(jīng)過(guò)網(wǎng)關(guān)的每一個(gè)請(qǐng)求,檢查 token 中的信息是否有效。
注意是“認(rèn)證檢查”,而不是“權(quán)限”,權(quán)限是在每個(gè)服務(wù)的Controller上貼權(quán)限注解
1. 功能介紹
1、在用戶完成登錄后,程序會(huì)把用戶相關(guān)的用戶、角色、權(quán)限等信息臨時(shí)存儲(chǔ)在 redis 中,并把token返回給終端用戶。
1、畢竟返回的token只存儲(chǔ)了極其少量的用戶信息,避免傳輸?shù)臄?shù)據(jù)量太大
2、RuoYi 返回的 token 中存儲(chǔ)的信息有:
user_key:login_tokens:uuid(存入redis中用的)
user_id:userId
username:userName
2、當(dāng)用戶攜帶token時(shí),我們判斷 token 是否有效,關(guān)聯(lián)的用戶是否登錄。如果token有效就把user_key、user_id、username 設(shè)置到請(qǐng)求頭中
此處主要是檢驗(yàn) token 是否有效。
設(shè)置到請(qǐng)求頭,統(tǒng)一處理,也方便其他模塊
2. AuthFilter的配置
@Component
public class AuthFilter implements GlobalFilter, Ordered
{
private static final Logger log = LoggerFactory.getLogger(AuthFilter.class);
@Autowired
private RedisService redisService;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
{
...
}
}
AuthFilter 實(shí)現(xiàn)了GlobalFilter, Ordered,是一個(gè)全局過(guò)濾器,所有的模塊都有。這也很好理解,所有的模塊當(dāng)然都需要檢查 token 是否有效啊。
3. AuthFilter實(shí)現(xiàn)分析
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
{
ServerHttpRequest request = exchange.getRequest();
ServerHttpRequest.Builder mutate = request.mutate();
String url = request.getURI().getPath();
// 1、檢驗(yàn)路徑
if (StringUtils.matches(url, ignoreWhite.getWhites()))
{
return chain.filter(exchange);
}
String token = getToken(request);
// 2、是否有token
if (StringUtils.isEmpty(token))
{
return unauthorizedResponse(exchange, "令牌不能為空");
}
// 3、解析token,判斷是否是有效的token
Claims claims = JwtUtils.parseToken(token);
if (claims == null)
{
return unauthorizedResponse(exchange, "令牌已過(guò)期或驗(yàn)證不正確!");
}
String userkey = JwtUtils.getUserKey(claims);
// 4、判斷用戶是否登錄
boolean islogin = redisService.hasKey(getTokenKey(userkey));
if (!islogin)
{
return unauthorizedResponse(exchange, "登錄狀態(tài)已過(guò)期");
}
String userid = JwtUtils.getUserId(claims);
String username = JwtUtils.getUserName(claims);
// 5、檢查token是否有userId、userName
if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username))
{
return unauthorizedResponse(exchange, "令牌驗(yàn)證失敗");
}
// 6、設(shè)置用戶信息到請(qǐng)求
addHeader(mutate, SecurityConstants.USER_KEY, userkey);
addHeader(mutate, SecurityConstants.DETAILS_USER_ID, userid);
addHeader(mutate, SecurityConstants.DETAILS_USERNAME, username);
// 7、內(nèi)部請(qǐng)求來(lái)源參數(shù)清除
removeHeader(mutate, SecurityConstants.FROM_SOURCE);
return chain.filter(exchange.mutate().request(mutate.build()).build());
}
1、檢驗(yàn)路徑
路徑uri白名單檢驗(yàn),如果是白名單,直接通過(guò)。
2、是否有token
3、解析token,判斷是否是有效的token
只有有效的 token 才會(huì)解析出信息而不報(bào)錯(cuò)。
4、判斷用戶是否登錄
auth 的權(quán)限校驗(yàn)有一個(gè)校驗(yàn)用戶是否登錄的注解。
5、檢查token是否有userId、userName
6、設(shè)置用戶信息到請(qǐng)求頭
7、內(nèi)部請(qǐng)求來(lái)源參數(shù)清除
8、繼續(xù)下一個(gè)過(guò)濾器文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-729830.html
4. 資料參考
語(yǔ)雀筆記地址:https://www.yuque.com/yuchangyuan/tkb5br文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-729830.html
到了這里,關(guān)于【RuoYi-Cloud項(xiàng)目研究】【ruoyi-gateway模塊】網(wǎng)關(guān)的AuthFilter完成“認(rèn)證”,注意是認(rèn)證而不是權(quán)限的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!