Un resumen de la solución al problema de la solicitud de recepción sin cookies

Hoy encontré un problema muy difícil: el front-end solicita el back-end sin cookies.

No hay ninguna cookie en el encabezado cuando se realiza la solicitud, es posible que falte algo más

Es un dolor de cabeza, probé muchos métodos, pero aún no puedo funcionar, como los siguientes:

1: Usé axios para solicitar. Muchas personas simplemente agregan la siguiente línea de código para hacerlo, pero no

// 允许携带cookie
axios.defaults.withCredentials=true

2: Luego, además de con Credenciales, alguien agregó algunas otras cosas para tener éxito, de la siguiente manera:

		//	设置
		axio.withCredentials = true;
		axio.defaults.withCredentials = true;
		
		//	或者这样设置
		axio.defaults.headers.post['Content-Type'] = 'application/json; charset=utf-8';
		axio.defaults.crossDomain = true;
		axio.defaults.withCredentials = true;  //设置cross跨域 并设置访问权限 允许跨域携带cookie信息
		axio.defaults.headers.common['Authorization'] = ''; // 设置请求头为 Authorization
		
		return axio.post(PATH.FINANCE_APL_LIST,data, {withCredentials:true
		}).then(res=>{
			console.log("OKOKOK2-------------------",res)
			return res.data.retObj
		})

Pero desafortunadamente, todavía fallé

 

3: Algunas personas dicen que agregue así, haga una configuración global:

import axios from "axios";
// Create an instance using the config defaults provided by the library
// At this point the timeout config value is `0` as is the default for the library
const axio = axios.create({
	headers: {
		"Content-Type": "application/json;charset=UTF-8"
	}
});

// Override timeout default for the library
// Now all requests using this instance will wait 2.5 seconds before timing out
axio.defaults.timeout = 200000;
axio.defaults.withCredentials = true;

Mismo principio, todavía falló

 

4: Algunos hermanos dijeron que el back-end también debería estar configurado:

[Access-Control-Allow-Credentials] debe ser verdadero

[Access-Control-Allow-Origin] Establecer que la IP permitida a la que se accede no puede ser [*], entrará en conflicto con Credentials = true

Entonces existen los siguientes controles:

4-1: Solo permita que su propio servidor de aplicaciones para el usuario acceda a:

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

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

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Component
public class CorsInterceptor implements HandlerInterceptor {

	public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o)
			throws Exception {

		// 设置允许多个域名请求
		String[] allowDomains = {
								"http://localhost:3010"
								};
		Set<String> allowOrigins = new HashSet<String>(Arrays.asList(allowDomains));
		String originHeads = httpServletRequest.getHeader("Origin");
		if(allowOrigins.contains(originHeads)){
			//设置允许跨域的配置
			// 这里填写你允许进行跨域的主机ip(正式上线时可以动态配置具体允许的域名和IP)
			httpServletResponse.setHeader("Access-Control-Allow-Origin", originHeads);
		}

		httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");

		httpServletResponse.setHeader("Access-Control-Allow-Headers",
				"Content-Type,Content-Length, Authorization, Accept,X-Requested-With");

		httpServletResponse.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");

		httpServletResponse.setHeader("X-Powered-By", "Jetty");

		String method = httpServletRequest.getMethod();
		System.out.println(method);
		if (method.equals("OPTIONS")) {

			httpServletResponse.setStatus(200);

			return false;
		}
		return true;
	}

	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
			ModelAndView modelAndView) throws Exception {

	}

	public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
			Object o, Exception e) throws Exception {

	}
}

4-2: Permitir el acceso de todos los servidores de aplicaciones para el usuario

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

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Component
public class CorsInterceptor implements HandlerInterceptor {

	public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o)
			throws Exception {
		String originHeads = httpServletRequest.getHeader("Origin");

		httpServletResponse.setHeader("Access-Control-Allow-Origin", originHeads);

		httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");

		httpServletResponse.setHeader("Access-Control-Allow-Headers",
				"Content-Type,Content-Length, Authorization, Accept,X-Requested-With");

		httpServletResponse.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");

		httpServletResponse.setHeader("X-Powered-By", "Jetty");

		String method = httpServletRequest.getMethod();
		System.out.println(method);
		if (method.equals("OPTIONS")) {

			httpServletResponse.setStatus(200);

			return false;
		}
		return true;
	}

	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
			ModelAndView modelAndView) throws Exception {

	}

	public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
			Object o, Exception e) throws Exception {

	}
}

Lo intenté todo, pero no funcionó.

 

5: Es mejor pensar y pensar, ¿es un problema de ingeniería inicial?

Entonces se agrega un método de prueba al controlador, porque el backend requiere verificación de permisos

Antes de iniciar sesión en el sistema, abre una nueva ventana para visitar directamente en el navegador, es con cookie:

 

Acceso directo en el navegador después de iniciar sesión, también con cookies:

 

Entonces hay una pequeña ceja, resumida de la siguiente manera:

1: No llame a través del proyecto de front-end, acceda directamente desde el navegador, llame al back-end mediante métodos como ajax / axios que no sean el proyecto de front-end, que puede llevar cookies

2: Utilice servicios de front-end locales, use axios, etc. para llamar al back-end, sin cookies

Entonces, compare el servicio local con el servicio implementado en el servidor:

Servicio de front-end local, acceso a back-end, sin cookies:

 

Sorprenda aquí, servicio front-end del servidor, acceso back-end, con Cookie

Esto puede ser un problema ambiental ,,,

Así que fui a Baidu, Google, y solo encontré uno que era algo similar:

Así que solo puedo pensar por mí mismo, piénselo, recuerde que hay una advertencia [Se muestran los encabezados provisionales] en el encabezado de la solicitud sin la cookie, de la siguiente manera:

 

Fue otra búsqueda, el siguiente hermano, que dijo bien, aunque no resolvió mi problema:

Pensando en nuestro hermano de front-end, parece haber agregado una configuración, no almacenar en caché los recursos solicitados, e ir al servidor para obtener el último cada vez. ¿Podría ser este el problema? El entorno de desarrollo y el entorno de producción están configurados para tener estrategias inconsistentes. ? Aunque la esperanza es escasa, lo probé

El código clave es el siguiente:

Lo probé varias veces, todavía se ve igual, lo que indica que este no es el problema

Busqué y busqué, busqué y busqué, y de repente recordé que el servidor estaba usando una imagen de Docker. El proyecto anterior usaba Nginx como proxy inverso. Esta debería ser la razón. Encontré dos artículos en Internet y encontré a estos dos hermanos. Así es:

Hermano uno:

1: la solución más simple y grosera

Modifique el directorio del proyecto, agregue una carpeta XXX, coloque los recursos estáticos y los archivos de página que necesita el entorno de desarrollo en la carpeta XXX y cambie la dirección del proyecto de acceso en el entorno de desarrollo a http: // localhost : 8485 / XXX. Obviamente, esta solución tiene fallas. Si la ruta de la cookie cambia, necesitamos cambiar la estructura del directorio del proyecto nuevamente, y es posible que también necesitemos modificar la configuración del paquete web (u otra configuración de empaquetado)

2: el camino del proxy nginx

3: solución webpack-dev-server

La idea clave es la anterior: si desea obtener más información, consulte el enlace: https://segmentfault.com/a/1190000013753896

Hermano dos:

La idea clave es la anterior: si desea saber más, consulte el enlace: https://www.jianshu.com/p/cadab71987d2

Entonces ... estoy aquí por hoy, agregue un servicio de agente mañana e intente, debería resolver el problema

 

Seguimiento: Efectivamente:

Se agrega un proxy a package.json para proxy de la dirección de backend para resolver el problema

 

Por supuesto, también puede usar Nginx como un proxy para acceder a la parte delantera y trasera

También es posible usar zuul como un proxy de puerta de enlace, todo el acceso al proyecto, primero vaya a zuul y luego reenvíe al servicio respectivo por zuul,

 

Todos los planes anteriores están bien, cruce el mar y muestre su magia.

Supongo que te gusta

Origin blog.csdn.net/u013282737/article/details/101001959
Recomendado
Clasificación