Teknologian jakaminen

Integroi sa-token, erota käyttöliittymän ja taustan käyttöönotto ja määritä corsFliter ratkaisemaan verkkotunnusten välisen epäonnistumisen todellinen syy.

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. Esittely

Katso syy seuraavaan artikkeliin: Oikea tapa ratkaista verkkotunnusten väliset ongelmat erottamalla sa-tokenin käyttöliittymä ja tausta

https://mp.weixin.qq.com/s/96WbWL28T5_-xzyCfJ7Stg
https://blog.csdn.net/qq_34905631/article/details/140233780?spm=1001.2014.3001.5501
  • 1
  • 2

Vaikka tämä artikkeli löysi oikean asennon monien yritysten jälkeen, ongelman perimmäistä syytä ei löytynyt. Sitten mietin hetken pohdiskelun jälkeen, voisiko tätä verkkotunnusten välistä simuloida paikallisesti, ja sitten aloin etsiä sitä Wang, hankkeen etupään henkilökunta, todellakin simuloi paikallista verkkotunnusten rajaa. Projektissa hän erotti edellisen sa-tokenin käyttöliittymän ja takapään ratkaistakseen verkkotunnusten välisen oikean asennon ja toisti ongelman. kommentoituaan artikkelin SimpleCORSFilteriä.

2. Ongelman toistuminen

Virallisen spring5.2.15.RELEASE mvc:n verkkotunnusten välinen kokoonpano on seuraava:

https://docs.spring.io/spring-framework/docs/5.2.15.RELEASE/spring-framework-reference/web.html#mvc-cors-intro
  • 1

Noudata yllä linkkittyä virallista menetelmää ja lisää sitten CustomCorsFilter-luokka seuraavasti:

package xxxx.config;

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;


@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomCorsFilter extends CorsFilter {

    public CustomCorsFilter() {
        super(corsConfigurationSource());
    }

    private static CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.addAllowedOrigin("*"); // 允许访问的域名,例如 http://localhost:8080
        configuration.addAllowedHeader("*"); // 允许所有请求头
        configuration.addAllowedMethod("*"); // 允许所有请求方法
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

CustomCorsFilterin konfiguraatio on todettu toimivaksi projektissa, jonka parissa olen työskennellyt. On kuitenkin hyödytöntä käyttää tätä CustomCorsFilter-luokan kokoonpanoa verkkotunnusten välisten ongelmien ratkaisemiseen. Yllä olevassa artikkelissa, joka käsittelee verkkotunnusten välisten ongelmien ratkaisemista erottamalla sa-token-etuosa ja taustaosa, CustomCorsFilter-luokan vahvistus oli todellakin virheellinen, kun määritin projektin CustomCorsFilter-luokan uudelleen , (SimpleCORSFilter on kommentoitava, koska tätä SimpleCORSFilteriä voidaan käyttää varmennuksen jälkeen, kun käyttöliittymä simuloi verkkotunnusten välisiä pyyntöjä, ja laitan seuraavaan CorsFilter-luokan koodiin:

   @Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
			FilterChain filterChain) throws ServletException, IOException {

		CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request);
		boolean isValid = this.processor.processRequest(corsConfiguration, request, response);
        //关键就是这里,在这里打上断点
		if (!isValid || CorsUtils.isPreFlightRequest(request)) {
			return;
		}
		filterChain.doFilter(request, response);
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Aseta myös keskeytyspiste CorsUtils.isPreFlightRequest-menetelmään:

	public static boolean isPreFlightRequest(HttpServletRequest request) {
		return (HttpMethod.OPTIONS.matches(request.getMethod()) &&
				request.getHeader(HttpHeaders.ORIGIN) != null &&
				request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) != null);
	}
  • 1
  • 2
  • 3
  • 4
  • 5

Sitten keskeytyspisteen kuvakaappaus on seuraava:

Kirjautumisliittymä on monimutkainen verkkotunnusten välinen pyyntö, jossa on http plus verkkotunnus, ja esitunnistuspyyntö (OPTIONS-pyyntö) lähetetään.

cors-virheenkorjaus kuva 2

Sa-tokeniin integroidussa projektissa asetin keskeytyskohdan OncePerRequestFilterin doFilterInternal-menetelmälle ja löysin seuraavat suodattimet:

cors-virheenkorjaus kuva 2

Voidaan nähdä, että edellä mukauttamamme CustomCorsFilter suoritetaan ensin ja kaksi sa-tokeniin liittyvää suodatinta: saPathCheckFilterForServlet ja SaServletFilter suoritetaan myöhemmin, joten muut aiemmat olettamukset ovat hyvin varmistuneet. Katkeuspiste menee CorsFilterin doFilterInternal-menetelmään :

       //关键就是这里,在这里打上断点
		if (!isValid || CorsUtils.isPreFlightRequest(request)) {
			return;
		}
  • 1
  • 2
  • 3
  • 4

Ongelma piilee seuraavassa koodissa:

CorsUtils.isPreFlightRequest(request)
  • 1

Tämä koodirivi palautti tosi, joten kaikkia myöhempiä suodattimia ei suoritettu, joten pyyntöä ei voitu saavuttaa. Selain raportoi edelleen verkkotunnusten välisistä ongelmista. , havaittiin, että sen jälkeen, kun monimutkainen pyyntö lähetti esitunnistuspyynnön (OPTIONS-pyynnön) verkkotunnuksille, alkuperä asetetaan selittämättömällä tavalla:

http://localhost:3000
  • 1

Tämä oli hyvin outoa, joten pyysin kollegaani Lao Wangia tarkistamaan, missä tämä arvo asetettiin, ja löysin seuraavan:

cors-virheenkorjaus kuva 3

Käyttöliittymä ei aseta alkuperää, vaan asettaa vain seuraavat parametrit:

//设置axios跨域访问
axios.defaults.withcredentials = true // 设置cross跨域 并设置访问权限 允许跨域携带cookie信息axios.defaults.crossDomain=true //设置axios跨域的配置
  • 1
  • 2

Yllä olevassa kuvassa on vain yksi viittausarvo, joka vastaa Origin-arvoa. Onko tämä todella vain sattumaa, joten luin seuraavan artikkelin:

https://blog.csdn.net/qq_55316925/article/details/128571809
  • 1

Se antoi minulle paljon ideoita, joten ajattelin sitä, ja kävi ilmi, että taustajärjestelmään määritetty CustomCorsFilter oli tehokas. Voinko muuttaa CorsFilterin lähdekoodia, joten kokeilin seuraavia kahta menetelmää, jotka olen vahvistanut Front-end Lao Wang, molemmat menetelmät ovat mahdollisia, ja kumpi tahansa voi ratkaista Cors cross-domain ongelma.

3. Ratkaisu

3.1 Tapa 1: Muokkaa CorsFilter-lähdekoodia taustalla

Muokkaa CorsFilter-lähdekoodia taustalla

Lisää uusi org.springframework.web.filter-paketti osoitteeseen src.main.java projektin alle

Kopioi sitten CorsFilterin lähdekoodi ja laita se yllä luodun org.springframework.web.filter-paketin alle, ja sitten voit muokata CorsFilterin lähdekoodia.

/*
 * Copyright 2002-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.web.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.util.Assert;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.CorsProcessor;
import org.springframework.web.cors.CorsUtils;
import org.springframework.web.cors.DefaultCorsProcessor;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

/**
 * {@link javax.servlet.Filter} that handles CORS preflight requests and intercepts
 * CORS simple and actual requests thanks to a {@link CorsProcessor} implementation
 * ({@link DefaultCorsProcessor} by default) in order to add the relevant CORS
 * response headers (like {@code Access-Control-Allow-Origin}) using the provided
 * {@link CorsConfigurationSource} (for example an {@link UrlBasedCorsConfigurationSource}
 * instance.
 *
 * <p>This is an alternative to Spring MVC Java config and XML namespace CORS configuration,
 * useful for applications depending only on spring-web (not on spring-webmvc) or for
 * security constraints requiring CORS checks to be performed at {@link javax.servlet.Filter}
 * level.
 *
 * <p>This filter could be used in conjunction with {@link DelegatingFilterProxy} in order
 * to help with its initialization.
 *
 * @author Sebastien Deleuze
 * @since 4.2
 * @see <a href="https://www.w3.org/TR/cors/">CORS W3C recommendation</a>
 */
public class CorsFilter extends OncePerRequestFilter {

	private final CorsConfigurationSource configSource;

	private CorsProcessor processor = new DefaultCorsProcessor();


	/**
	 * Constructor accepting a {@link CorsConfigurationSource} used by the filter
	 * to find the {@link CorsConfiguration} to use for each incoming request.
	 * @see UrlBasedCorsConfigurationSource
	 */
	public CorsFilter(CorsConfigurationSource configSource) {
		Assert.notNull(configSource, "CorsConfigurationSource must not be null");
		this.configSource = configSource;
	}


	/**
	 * Configure a custom {@link CorsProcessor} to use to apply the matched
	 * {@link CorsConfiguration} for a request.
	 * <p>By default {@link DefaultCorsProcessor} is used.
	 */
	public void setCorsProcessor(CorsProcessor processor) {
		Assert.notNull(processor, "CorsProcessor must not be null");
		this.processor = processor;
	}


	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
			FilterChain filterChain) throws ServletException, IOException {

		CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request);
		boolean isValid = this.processor.processRequest(corsConfiguration, request, response);
		//修改的源码是将CorsUtils.isPreFlightRequest(request)这行代码移除,就是因为复杂请求跨域发了预检测请求,浏览器的referrer-policy引用者策略会携带一个值,后端处理之后会将这个值赋值给请求头的Orgin属性上,移除这行代码之后就可以正常访问到登录接口了,前端也没有报跨域了。
        if (!isValid) {
			return;
		}
		filterChain.doFilter(request, response);
	}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97

3.2 Tapa 2: Poista käytöstä tai poista selaimen viittauskäytäntö käyttöliittymästä

Lisää käyttöliittymään seuraava koodi: poista viittauskäytännön viittauskäytäntö käytöstä tai poista se

https://blog.csdn.net/qq_49810363/article/details/111036180
  • 1

Uusi koodi on seuraava:

<meta name="referrer" content="never">
  • 1

cors-virheenkorjaus kuva 4

Selaimen viittauskäytäntö on myös turvallisuussyistä. Käyttämäni selain on Chrome-selain.

4. Yhteenveto

Jatkuvien yritysten ja haparoiden jälkeen Cors-verkkotunnusten käyttöönoton ongelma ilmeni yleisesti ottaen cors cross-domain -protokollan spesifikaatiot eivät salli tätä toimintaa -end-ratkaisukirjasto ei salli pyyntötoimintoja, jotka eivät noudata cors cross-domain -protokollan määrityksiä, joten voit käyttää sa-tokenia erottamaan etu- ja taustaratkaisut verkkotunnusten välisten ratkaisujen oikeaan asentoon. SimpleCORSFilterin määrittäminen, tiettyjen parametrien kirjoittaminen ja käsittely Esitunnistuspyyntö palauttaa tilakoodin 200, tai voit käyttää jompaakumpaa tämän artikkelin kahdesta menetelmästä verkkotunnusten välisen ongelman ratkaisemiseen Teen virheenkorjauksen sen jälkeen, kun olen toistanut verkkotunnusten välisen pyynnön katkaisupisteessä. Ratkaisu. Jos uskot, että voit noudattaa tämän artikkelin menetelmää, toista verkkotunnusten välinen pyyntö paikallisesti ja korjaa sitten katkaisukohta, jotta näet, onko kyseessä ongelma. CorsUtils.isPreFlightRequest(request) -rivi Yleensä tämä verkkotunnusten välinen ongelma on suuri ongelma selaimille. Yksinkertainen pyyntö corsFilterille ei epäonnistu. Koska selaimen viittauskäytännössä on arvo, taustakäsittelyn jälkeen tämä arvo määritetään pyynnön otsikon Origin-attribuutille, jolloin corsFilter-koodirivi CorsUtils.isPreFlightRequest(request) palauttaa arvon tosi. ja sitten palaa. Tämän seurauksena seuraavan suodatinsarjan doFilteriä ei suoriteta, ja taustakäyttöliittymään ei ole pääsyä, ja käyttöliittymäsivu raportoi edelleen verkkotunnusten välisistä ongelmista , tämä ongelma on todella ärsyttävä. https-menetelmä ei toimi verkkotunnusten välillä, koska https kuuntelee porttia 443 ja vaatii varmenteen määrittämistä. Tämä artikkeli poistaa syytteen siitä, että sa-tokenin integrointi saa aikaan sen on sama Internetissä. Tässä artikkelissa ei ole ratkaisua. Luominen ei ole helppoa. Älä plagioi sitä alkuperäinen Tulosta ja lisää alkuperäinen lähde. Toivon, että jakaminen voi inspiroida ja auttaa sinua muodostamaan yhteyden.