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

解決跨域請求,NG返回403(403并不一定是NG問題)

 更新時間:2023年12月26日 09:30:28   作者:zero  
這篇文章主要介紹了解決跨域請求,NG返回403(403并不一定是NG問題),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

先說問題怎么解決的

1.ng返回403的情況也就那么幾種,百度一下都能找到,但是ng返回403不一定是ng的問題。

2.最終發(fā)現(xiàn)是在網(wǎng)關(guān)跨域配置中,沒有加上請求方的域名。

3.想探索的可以看看文章

背景

和合作方對接,我們這邊的app開發(fā)完放在合作方的服務(wù)器上,再通過NG,請求我這邊的后臺。

NG配置跨域等信息后(這個很容易找,百度隨便都能找到),發(fā)現(xiàn)測試環(huán)境一切正常,但是到了生產(chǎn),NG一直返回403。

請求都沒通過,網(wǎng)關(guān)zuul沒有日志。雙方開始排查NG,百度了無數(shù)次。

最后都配置與測試環(huán)境一直,但是生產(chǎn)一直不通。

返回403,加上zuul沒日志,一直定位在NG跨域的問題上。

解決

最后發(fā)現(xiàn)是zuul項(xiàng)目的問題,SpringBoot跨域問題。

嘗試排查是否zuul的問題,對比了測試環(huán)境和生產(chǎn)的。

測試環(huán)境zuul的跨域配置CorsConfiguration類屬性allowedOrigins賦值了個*,生產(chǎn)是針對地址進(jìn)行配置的。

其實(shí)就是SpringBoot的跨域配置,源碼CorsConfiguration的allowedOrigins屬性沒有加上第三方的域名地址。

導(dǎo)致直接被拒絕了。加上合作方地址,問題解決。

源碼解析

在配置跨域問題時,我們需要對CorsConfiguration屬性賦值

//對CorsConfiguration屬性賦值
private CorsConfiguration corsConfig(Map.Entry<String, JawsCorsConfig> entry) {
    CorsConfiguration corsConfiguration = new CorsConfiguration();
    corsConfiguration.setAllowedOrigins(Splitter.on(",").splitToList(entry.getValue().getAllowedOrigins()));
    corsConfiguration.setAllowedHeaders(Splitter.on(",").splitToList(entry.getValue().getAllowedHeaders()));
    corsConfiguration.setAllowedMethods(Splitter.on(",").splitToList(entry.getValue().getAllowedMethods()));
    corsConfiguration.setAllowCredentials(entry.getValue().getAllowCredentials());
    corsConfiguration.setMaxAge(entry.getValue().getMaxAge());
    return corsConfiguration;
}

@Bean
    public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    for (Map.Entry<String, JawsCorsConfig> entry : jawsZuulProperites.getCors().entrySet()) {
        source.registerCorsConfiguration(entry.getValue().getUrls(), corsConfig(entry));
    }
    return new CorsFilter(source);
}

源碼中 org.springframework.web.cors.DefaultCorsProcessor#handleInternal 方法

protected boolean handleInternal(ServerHttpRequest request, ServerHttpResponse response,
			CorsConfiguration config, boolean preFlightRequest) throws IOException {

		String requestOrigin = request.getHeaders().getOrigin();
		String allowOrigin = checkOrigin(config, requestOrigin);

		HttpMethod requestMethod = getMethodToUse(request, preFlightRequest);
		List<HttpMethod> allowMethods = checkMethods(config, requestMethod);

		List<String> requestHeaders = getHeadersToUse(request, preFlightRequest);
		List<String> allowHeaders = checkHeaders(config, requestHeaders);

		if (allowOrigin == null || allowMethods == null || (preFlightRequest && allowHeaders == null)) {
			rejectRequest(response);
			return false;
		}

		HttpHeaders responseHeaders = response.getHeaders();
		responseHeaders.setAccessControlAllowOrigin(allowOrigin);
		responseHeaders.add(HttpHeaders.VARY, HttpHeaders.ORIGIN);

		if (preFlightRequest) {
			responseHeaders.setAccessControlAllowMethods(allowMethods);
		}

		if (preFlightRequest && !allowHeaders.isEmpty()) {
			responseHeaders.setAccessControlAllowHeaders(allowHeaders);
		}

		if (!CollectionUtils.isEmpty(config.getExposedHeaders())) {
			responseHeaders.setAccessControlExposeHeaders(config.getExposedHeaders());
		}

		if (Boolean.TRUE.equals(config.getAllowCredentials())) {
			responseHeaders.setAccessControlAllowCredentials(true);
		}

		if (preFlightRequest && config.getMaxAge() != null) {
			responseHeaders.setAccessControlMaxAge(config.getMaxAge());
		}

		response.flush();
		return true;
	}
	

進(jìn)入checkOrigin(config, requestOrigin);校驗(yàn)請求來源

	public static final String ALL = "*";
	/**
	 * Check the origin of the request against the configured allowed origins.
	 * @param requestOrigin the origin to check
	 * @return the origin to use for the response, or {@code null} which
	 * means the request origin is not allowed
	 */
	public String checkOrigin(String requestOrigin) {
		if (!StringUtils.hasText(requestOrigin)) {
			return null;
		}
		if (ObjectUtils.isEmpty(this.allowedOrigins)) {
			return null;
		}

		if (this.allowedOrigins.contains(ALL)) {
			if (this.allowCredentials != Boolean.TRUE) {
				return ALL;
			}
			else {
				return requestOrigin;
			}
		}
//遍歷我們賦值的allowedOrigins,判斷請求來源是否包含,包含則返回
		for (String allowedOrigin : this.allowedOrigins) {
			if (requestOrigin.equalsIgnoreCase(allowedOrigin)) {
				return requestOrigin;
			}
		}
return null;
}
		

總結(jié)

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • spring?NamedContextFactory在Fegin配置及使用詳解

    spring?NamedContextFactory在Fegin配置及使用詳解

    在我們?nèi)粘m?xiàng)目中,使用FeignClient實(shí)現(xiàn)各系統(tǒng)接口調(diào)用變得更加簡單,?在各個系統(tǒng)集成過程中,難免會遇到某些系統(tǒng)的Client需要特殊的配置、返回讀取等需求。Feign使用NamedContextFactory來為每個Client模塊構(gòu)造單獨(dú)的上下文(ApplicationContext)
    2023-11-11
  • Java消息隊(duì)列RabbitMQ之消息回調(diào)詳解

    Java消息隊(duì)列RabbitMQ之消息回調(diào)詳解

    這篇文章主要介紹了Java消息隊(duì)列RabbitMQ之消息回調(diào)詳解,消息回調(diào),其實(shí)就是消息確認(rèn)(生產(chǎn)者推送消息成功,消費(fèi)者接收消息成功)  , 對于程序來說,發(fā)送者沒法確認(rèn)是否發(fā)送成功,需要的朋友可以參考下
    2023-07-07
  • Java的MyBatis+Spring框架中使用數(shù)據(jù)訪問對象DAO模式的方法

    Java的MyBatis+Spring框架中使用數(shù)據(jù)訪問對象DAO模式的方法

    Data Access Object數(shù)據(jù)訪問對象模式在Java操作數(shù)據(jù)庫部分的程序設(shè)計(jì)中經(jīng)常被使用到,這里我們就來看一下Java的MyBatis+Spring框架中使用數(shù)據(jù)訪問對象DAO模式的方法:
    2016-06-06
  • Spring Boot @Async 異步任務(wù)執(zhí)行方法

    Spring Boot @Async 異步任務(wù)執(zhí)行方法

    本篇文章主要介紹了Spring Boot @Async 異步任務(wù)執(zhí)行方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • java調(diào)用opencv身份證號識別詳解

    java調(diào)用opencv身份證號識別詳解

    這篇文章主要為大家詳細(xì)介紹了java如何調(diào)用opencv實(shí)現(xiàn)身份證號的識別,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03
  • SpringBoot中添加監(jiān)聽器及創(chuàng)建線程的代碼示例

    SpringBoot中添加監(jiān)聽器及創(chuàng)建線程的代碼示例

    這篇文章主要介紹了SpringBoot中如何添加監(jiān)聽器及創(chuàng)建線程,文中有詳細(xì)的代碼示例,具有一定的參考價值,需要的朋友可以參考下
    2023-06-06
  • SpringBoot?Java通過API的方式調(diào)用騰訊智能體(騰訊元寶)代碼示例

    SpringBoot?Java通過API的方式調(diào)用騰訊智能體(騰訊元寶)代碼示例

    這篇文章主要介紹了SpringBoot?Java通過API的方式調(diào)用騰訊智能體(騰訊元寶)的相關(guān)資料,詳細(xì)說明參數(shù)獲取及動態(tài)處理方法,提供結(jié)果字符串轉(zhuǎn)數(shù)組技巧,需要的朋友可以參考下
    2025-06-06
  • Java中Runnable和Thread的區(qū)別分析

    Java中Runnable和Thread的區(qū)別分析

    在java中可有兩種方式實(shí)現(xiàn)多線程,一種是繼承Thread類,一種是實(shí)現(xiàn)Runnable接口,下面就拉分別介紹一下這兩種方法的優(yōu)缺點(diǎn)
    2013-03-03
  • Java 遞歸查詢部門樹形結(jié)構(gòu)數(shù)據(jù)的實(shí)踐

    Java 遞歸查詢部門樹形結(jié)構(gòu)數(shù)據(jù)的實(shí)踐

    本文主要介紹了Java 遞歸查詢部門樹形結(jié)構(gòu)數(shù)據(jù)的實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • java實(shí)現(xiàn)ArrayList根據(jù)存儲對象排序功能示例

    java實(shí)現(xiàn)ArrayList根據(jù)存儲對象排序功能示例

    這篇文章主要介紹了java實(shí)現(xiàn)ArrayList根據(jù)存儲對象排序功能,結(jié)合實(shí)例形式分析了java針對ArrayList的相關(guān)運(yùn)算、排序操作技巧,需要的朋友可以參考下
    2018-01-01

最新評論

镇沅| 涟源市| 贵定县| 虞城县| 东阳市| 三门峡市| 定边县| 江城| 芦溪县| 泰顺县| 四平市| 海兴县| 同心县| 五寨县| 静宁县| 社会| 邵阳县| 萍乡市| 平阳县| 武邑县| 霍州市| 城步| 永登县| 黄梅县| 石首市| 环江| 房产| 工布江达县| 石门县| 海伦市| 浪卡子县| 武鸣县| 久治县| 山阳县| 六安市| 策勒县| 友谊县| 弥勒县| 文成县| 通城县| 清涧县|