最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringCloudGateway 網(wǎng)關(guān)登錄校驗實現(xiàn)思路

 更新時間:2024年11月11日 11:20:00   作者:cyt濤  
文章介紹了在微服務(wù)架構(gòu)中使用Spring Cloud Gateway進行登錄校驗的方法,通過在網(wǎng)關(guān)層面進行登錄校驗,并將用戶信息通過請求頭傳遞給下游微服務(wù),解決了每個微服務(wù)都需要獨立進行登錄校驗的問題,此外,還討論了如何在微服務(wù)之間傳遞用戶信息

單體架構(gòu)時我們只需要完成一次用戶登錄、身份校驗,就可以在所有業(yè)務(wù)中獲取到用戶信息。而微服務(wù)拆分后,每個微服務(wù)都獨立部署,不再共享數(shù)據(jù)。也就意味著每個微服務(wù)都需要做登錄校驗,這顯然不可取。

1. 思路分析

既然網(wǎng)關(guān)是所有微服務(wù)的入口,一切請求都需要先經(jīng)過網(wǎng)關(guān)。我們完全可以把登錄校驗的工作放到網(wǎng)關(guān)去做。

不過,這里存在幾個問題:

(1)網(wǎng)關(guān)路由是配置的,請求轉(zhuǎn)發(fā)是Gateway內(nèi)部代碼,我們?nèi)绾卧谵D(zhuǎn)發(fā)之前做登錄校驗?

        可以使用網(wǎng)關(guān)過濾器。

(2)網(wǎng)關(guān)校驗JWT之后,如何將用戶信息傳遞給微服務(wù)?

        由于網(wǎng)關(guān)發(fā)送請求到微服務(wù)依然采用的是Http請求,因此我們可以將用戶信息以請求頭的方式傳遞到下游微服務(wù)。然后微服務(wù)可以從請求頭中獲取登錄用戶信息。

(3)微服務(wù)之間也會相互調(diào)用,這種調(diào)用不經(jīng)過網(wǎng)關(guān),又該如何傳遞用戶信息?

        在微服務(wù)發(fā)起調(diào)用時把用戶信息存入請求頭。

2. 登錄校驗過濾器

白名單的配置:

application.ymlapplication.properties 文件中配置不需要攔截的路徑白名單。

gateway:
  ignoreUrls:
    - /auth/login
    - /auth/register
    - /public/**

在這個示例中,/auth/login、/auth/register、/public/** 等路徑將不需要進行登錄校驗。

package com.cyt.gateway.filter;
@Component // 聲明為Spring容器中的一個Bean
@RequiredArgsConstructor // 生成構(gòu)造方法,注入final成員變量
@EnableConfigurationProperties(AuthProperties.class) // 啟用配置類AuthProperties的屬性注入
public class AuthGlobalFilter implements GlobalFilter, Ordered {
    // 從配置文件中注入白名單路徑列表,用于存放不需要JWT校驗的路徑
    @Value("${gateway.ignoreUrls}")
    private List<String> ignoreUrls;
    private final JwtTool jwtTool; // JWT工具類,用于解析和校驗JWT
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1. 獲取Request對象,以訪問請求的相關(guān)信息
        ServerHttpRequest request = exchange.getRequest();
        // 2. 判斷請求路徑是否在白名單中(無需JWT校驗)
        if (isIgnoreUrl(request.getPath().toString())) {
            // 路徑在白名單中,直接放行請求
            return chain.filter(exchange);
        }
        // 3. 獲取請求頭中的token(假設(shè)token放在"authorization"頭部)
        String token = null;
        List<String> headers = request.getHeaders().get("authorization");
        if (!CollUtils.isEmpty(headers)) { // 如果請求頭包含authorization字段
            token = headers.get(0); // 獲取第一個token值
        }
        // 4. 使用jwtTool校驗并解析token
        Long userId = null;
        try {
            userId = jwtTool.parseToken(token); // 解析并獲取用戶ID
        } catch (UnauthorizedException e) {
            // 如果token無效或解析失敗,則返回401狀態(tài)碼并攔截請求
            ServerHttpResponse response = exchange.getResponse();
            response.setRawStatusCode(401);
            return response.setComplete(); // 返回空的響應(yīng)結(jié)束處理
        }
        // TODO 5. 如果token有效,可在此處傳遞用戶信息(如通過exchange.getAttributes())
        System.out.println("userId = " + userId); // 打印用戶ID供調(diào)試
        // 6. 放行請求
        return chain.filter(exchange);
    }
    /**
     * 判斷路徑是否在白名單中
     *
     * @param path 請求路徑
     * @return 如果路徑在白名單中返回true,否則返回false
     */
    private boolean isIgnoreUrl(String path) {
        for (String ignoreUrl : ignoreUrls) {
            // 使用正則匹配白名單路徑中的通配符 "**"
            if (path.matches(ignoreUrl.replace("**", ".*"))) {
                return true; // 路徑匹配白名單中的某一項,返回true
            }
        }
        return false; // 沒有匹配到任何白名單路徑,返回false
    }
    @Override
    public int getOrder() {
        return 0; // 設(shè)置過濾器優(yōu)先級,值越小優(yōu)先級越高
    }
}

3. 保存用戶到請求頭

5.6.部分代碼可以參照下面修改:

// 5.傳遞用戶信息
// 將解析出的用戶ID轉(zhuǎn)換為字符串,以便可以在請求頭中傳遞
String userInfo = userId.toString();
// 使用 exchange.mutate() 方法創(chuàng)建一個新的 ServerWebExchange 對象,
// 該對象將攜帶額外的請求頭 "user-info",包含用戶ID信息。
// .mutate() 方法用于復(fù)制當(dāng)前請求并進行修改。
// 在這里,我們使用 request(builder -> builder.header(...)) 方式為請求添加一個新的頭部。
ServerWebExchange modifiedExchange = exchange.mutate()
        .request(builder -> builder.header("user-info", userInfo)) // 將 "user-info" 頭設(shè)置為用戶ID字符串
        .build(); // 完成新的 ServerWebExchange 對象的構(gòu)建
// 6.放行
// 使用修改后的 ServerWebExchange 對象繼續(xù)執(zhí)行過濾鏈。
// 這樣,下游服務(wù)可以通過 "user-info" 請求頭獲取到用戶ID信息。
return chain.filter(modifiedExchange);

4. OpenFeign傳遞用戶

在微服務(wù)發(fā)起調(diào)用時把用戶信息存入請求頭。

如何才能讓每一個由OpenFeign發(fā)起的請求自動攜帶登錄用戶信息呢?

這里要借助Feign中提供的一個攔截器接口:feign.RequestInterceptor

我們只需要實現(xiàn)這個接口,然后實現(xiàn)apply方法,利用RequestTemplate類來添加請求頭,將用戶信息保存到請求頭中。

可以在OpenFeign的配置類中添加一個Bean:

@Bean
public RequestInterceptor userInfoRequestInterceptor(){
    // 定義一個 Feign 的 RequestInterceptor Bean,用于在請求發(fā)出前執(zhí)行自定義攔截操作
    return new RequestInterceptor() {
        @Override
        public void apply(RequestTemplate template) {
            // 獲取當(dāng)前登錄用戶的ID
            // UserContext 是一個上下文工具類,用于存儲和獲取當(dāng)前線程的用戶信息
            Long userId = UserContext.getUser();
            // 檢查用戶ID是否為 null,如果為 null 則表示用戶未登錄或無法獲取用戶信息
            if(userId == null) {
                // 如果用戶ID為空,不做任何處理,直接返回,跳過攔截器邏輯
                return;
            }
            // 如果用戶ID不為空,將用戶ID作為請求頭添加到 Feign 請求中
            // "user-info" 是請求頭的鍵,下游微服務(wù)可以從該請求頭中獲取用戶ID
            template.header("user-info", userId.toString());
        }
    };
}

5. 總結(jié)

思路分析中提到的三個問題,目前已經(jīng)全部解決。

接下來,微服務(wù)需要用戶信息,只需要編寫攔截器,獲取用戶信息并保存到ThreadLocal中,然后放行即可。

由于每個微服務(wù)都有獲取登錄用戶的需求,因此攔截器可以直接寫在common公共服務(wù)中,并寫好自動裝配。這樣微服務(wù)只需要引入common就可以直接具備攔截器功能,無需重復(fù)編寫。

到此這篇關(guān)于SpringCloudGateway 網(wǎng)關(guān)登錄校驗的文章就介紹到這了,更多相關(guān)SpringCloudGateway 登錄校驗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • BlockingQueue隊列處理高并發(fā)下的日志

    BlockingQueue隊列處理高并發(fā)下的日志

    這篇文章主要介紹了BlockingQueue隊列處理高并發(fā)下的日志示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-03-03
  • Spring Boot 集成 InfluxDB 3.x完整教程

    Spring Boot 集成 InfluxDB 3.x完整教程

    本文詳細介紹了如何在SpringBoot項目中集成InfluxDB3.x,并提供了一個完整的教程,包括環(huán)境準備、添加依賴、配置連接信息、創(chuàng)建客戶端配置類、數(shù)據(jù)寫入與查詢示例以及關(guān)鍵注意事項,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • Lambda表達式下訪問外部變量問題

    Lambda表達式下訪問外部變量問題

    這篇文章主要介紹了Lambda表達式下訪問外部變量問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Java線程數(shù)究竟設(shè)多少合理

    Java線程數(shù)究竟設(shè)多少合理

    這篇文章主要介紹了Java線程數(shù)究竟設(shè)多少合理,對線程感興趣的同學(xué),可以參考下
    2021-04-04
  • java繼承學(xué)習(xí)之super的用法解析

    java繼承學(xué)習(xí)之super的用法解析

    本文介紹java繼承super的用法,Java繼承是會用已存在的類的定義作為基礎(chǔ)建立新類的技術(shù)新類的定義可以增加新的數(shù)據(jù)或者新的功能,也可以使用父類的功能,但不能選擇性的繼承父類 這種繼承使得復(fù)用以前的代碼非常容易,能夠大大的縮短開發(fā)的周期,需要的朋友可以參考下
    2022-02-02
  • SpringBoot+Querydsl?框架實現(xiàn)復(fù)雜查詢解析

    SpringBoot+Querydsl?框架實現(xiàn)復(fù)雜查詢解析

    本篇主要將介紹的是利用spring query dsl框架實現(xiàn)的服務(wù)端查詢解析和實現(xiàn)介紹,對SpringBoot?Querydsl?查詢操作感興趣的朋友一起看看吧
    2022-05-05
  • druid連接池的參數(shù)配置示例全面解析

    druid連接池的參數(shù)配置示例全面解析

    這篇文章主要為大家介紹了druid連接池的參數(shù)配置示例全面解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • SpringBoot 裝飾器@TableField原理解析

    SpringBoot 裝飾器@TableField原理解析

    本文解析了MyBatis-Plus的@TableField注解,用于非主鍵字段與數(shù)據(jù)庫列的映射及行為控制,涵蓋自動填充、樂觀鎖、多租戶等企業(yè)級功能,提供使用技巧、常見問題及示例代碼,感興趣的朋友跟隨小編一起看看吧
    2025-09-09
  • Java中enum枚舉類型的基本特性詳解

    Java中enum枚舉類型的基本特性詳解

    這篇文章主要介紹了Java中enum枚舉類型的基本特性詳解,enum關(guān)鍵字用于創(chuàng)建一個新類型,其中包含一組數(shù)量有限的命名變量,并視這些變量為常規(guī)程序組件,實踐表明這是一種非常有用的類型,需要的朋友可以參考下
    2023-11-11
  • Java項目中如何訪問WEB-INF下jsp頁面

    Java項目中如何訪問WEB-INF下jsp頁面

    這篇文章主要介紹了Java項目中如何訪問WEB-INF下jsp頁面,文章通過示例代碼和圖文解析介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08

最新評論

灵丘县| 昌宁县| 峨眉山市| 永胜县| 苏尼特右旗| 西安市| 泽州县| 旬邑县| 扎赉特旗| 林西县| 乌拉特后旗| 清丰县| 永平县| 都匀市| 陆川县| 通化市| 榆中县| 商城县| 桐乡市| 县级市| 郁南县| 舒城县| 安阳市| 隆昌县| 红原县| 中西区| 永仁县| 永宁县| 永定县| 衡阳县| 合川市| 静乐县| 青川县| 海伦市| 黔南| 同心县| 咸阳市| 于都县| 辽源市| 汾西县| 沛县|