[RuoYi プロジェクト分析] ゲートウェイの AuthFilter が「認証」を完了します。これは権限ではなく認証であることに注意してください。


フィルターの機能は、ゲートウェイを通過するすべてのリクエストをチェックし、トークン内の情報が有効かどうかを確認することです。
「許可」ではなく「認証チェック」であることに注意してください。

1. 機能紹介

1. ユーザーがログインを完了すると、プログラムはユーザー関連のユーザー、ロール、権限、その他の情報を Redis に一時的に保存し、トークンをエンド ユーザーに返します。

1. 結局のところ、返されたトークンには、大量のデータの送信を避けるために、非常に少量のユーザー情報のみが保存されます 2.
RuoYi によって返されたトークンに保存される情報は次のとおりです:
user_key:login_tokens:uuid (redis に保存するために使用)
user_id : userId
ユーザー名: userName

2. ユーザーがトークンを携帯している場合、トークンが有効かどうか、および関連付けられたユーザーがログインしているかどうかを判断します。トークンが有効な場合は、user_key、user_id、および username をリクエスト ヘッダーに設定します。

ここでの主な目的は、トークンが有効かどうかを確認することです。
リクエストヘッダーに設定して一律に処理すると他のモジュールにも便利です。

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 は GlobalFilter、Ordered を実装しており、すべてのモジュールが持つグローバル フィルターです。これもわかりやすいですが、当然のことながら、すべてのモジュールでトークンが有効かどうかを確認する必要があります。

3. AuthFilter 実装の分析

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
    {
    
    
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpRequest.Builder mutate = request.mutate();

        String url = request.getURI().getPath();
        // 1、检验路径
        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, "令牌已过期或验证不正确!");
        }
        String userkey = JwtUtils.getUserKey(claims);
        // 4、判断用户是否登录
        boolean islogin = redisService.hasKey(getTokenKey(userkey));
        if (!islogin)
        {
    
    
            return unauthorizedResponse(exchange, "登录状态已过期");
        }
        String userid = JwtUtils.getUserId(claims);
        String username = JwtUtils.getUserName(claims);
        // 5、检查token是否有userId、userName
        if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username))
        {
    
    
            return unauthorizedResponse(exchange, "令牌验证失败");
        }

        // 6、设置用户信息到请求
        addHeader(mutate, SecurityConstants.USER_KEY, userkey);
        addHeader(mutate, SecurityConstants.DETAILS_USER_ID, userid);
        addHeader(mutate, SecurityConstants.DETAILS_USERNAME, username);
        // 7、内部请求来源参数清除
        removeHeader(mutate, SecurityConstants.FROM_SOURCE);
        return chain.filter(exchange.mutate().request(mutate.build()).build());
    }

1. パスを確認します。
パス URI はホワイトリストに登録されています。ホワイトリストに含まれている場合は、直接通過します。
2. トークンが存在するかどうか
3. トークンを解析し、有効なトークンかどうかを判断します
有効なトークンのみが、エラーを報告せずに情報を解析します。
4.
ユーザーがログインしているかどうかを判断するための auth の権限検証には、ユーザーがログインしているかどうかを検証するためのアノテーションが付いています。
5. トークンに userId と userName があるかどうかを確認します。
6. リクエスト ヘッダーにユーザー情報を設定します。
7. リクエスト ソースの内部パラメーターをクリアします
。 8. 次のフィルターに進みます。

4. 情報参照

Yuque ノートのアドレス: https: //www.yuque.com/yuchangyuan/tkb5br

おすすめ

転載: blog.csdn.net/yuchangyuan5237/article/details/133473706