El problema de que la sesión no se puede obtener normalmente debido a la separación de las páginas front-end y back-end

       Solución a problemas entre dominios y pérdida de sesión causada por la separación de las páginas de front-end y back-end

Nuevos estudiantes, lean este nuevo artículo. Este artículo ya no es aplicable:   Análisis del problema de inicio de sesión repetido en la nueva versión del navegador Chrome.

 Hace unos días me encontré con un problema que me llevó mucho tiempo encontrar debido a mi falta de experiencia. Es la interfaz del servidor Java que escribí en la máquina virtual de mi computadora. Al iniciar sesión y verificar la interfaz de inicio de sesión, la sesión se usa para almacenar datos del usuario. Cuando se coloca el html en mi proyecto, el valor de la sesión se puede obtener muy bien. , pero cuando el html se coloca en la computadora del personal de front-end, la sesión no puede obtener el valor correspondiente.

Después de buscar en línea, descubrí que se trata de un problema causado por la separación de las páginas de front-end y back-end. Muchos internautas ya han dicho muy buenas soluciones específicas. Para soluciones específicas, puede ver aquí el proyecto de separación de front-end y back-end, que admite dominios cruzados y no se pierde la sesión_la sesión no se pierde cuando se implementa en diferentes ubicaciones antes y después del blog-CSDN de woshiyeguiren .

Entonces permítanme hacer un anuncio: han pasado casi dos semanas desde que desbloqueé Java por primera vez y creé una biblioteca de materiales pbr para mi empresa. Los amigos interesados ​​pueden echar un vistazo y hacer clic para abrir el enlace.

2018.10.24 añadido:

Aunque encontré este problema cuando entré en contacto con Java por primera vez, todavía no esperaba que me tomara tanto tiempo encontrar el mismo problema más adelante. Proporcionaré suplementos detallados sobre cómo lidiar con varias situaciones.

Los problemas entre dominios son muy comunes en el desarrollo web, al implementar nuestro proyecto, por ejemplo, si ponemos el código front-end en un servidor (oss) y el código back-end en otro servidor, habrá problemas entre dominios. sin ningún reenvío o configuración entre los dos problemas de dominio. En segundo lugar, debido al uso del desarrollo de interfaces, el código de front-end inevitablemente se colocará en la computadora del personal de front-end y el código de back-end se colocará en la computadora del personal de back-end. Esto también causará problemas entre dominios. Sin embargo, al acoplar la interfaz y permitir que el personal de front-end acceda directamente a las computadoras del personal de back-end, los problemas se pueden informar claramente a ambas partes. La modificación directa de esta manera debería ser un proceso de desarrollo muy rápido. Por lo tanto, no consideramos si habrá problemas entre dominios al implementar en servidores en línea, todos necesitamos resolver los problemas entre dominios causados ​​por la segunda situación y el problema de la pérdida de sesión.

1: método de procesamiento en segundo plano del método de escritura nativo de Java

①: En segundo plano, escribimos una interfaz de devolución de solicitud unificada y configuramos el encabezado. Se llama uniformemente cuando se devuelven datos solicitados.

  // 返回json字符串数据
    void post_jsondata(HttpServletRequest request, HttpServletResponse response, JSONObject output)
            throws ServletException, IOException {
        response.setContentType("text/html");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");//是否支持跨域
        response.setHeader("Access-Control-Allow-Methods", "GET,POST");
        PrintWriter out = response.getWriter();
        out.println(output.toString());
        out.flush();
        out.close();
        // super.doPost(request, response);
    }

②: En el código de la página de inicio, incluimos el atributo xhrFields: {withCredentials: true} en la solicitud ajax, lo que significa proporcionar información de cookies.

<button id="buttom2b">用户端-测试按钮2</button>
    <script type="text/javascript">
        $("#buttom2b").click(function() {
            var shit = {
                    store_id:2
            };
            $.ajax({
                type : 'post',
                url : "http://192.168.0.15:8080/carplatform/User/test2",
                dataType : 'json',
                contentType : "application/json;charset=UTF-8",
                data : JSON.stringify(shit),
                xhrFields: {withCredentials: true},
                success : function(xxx) {
                console.log(xxx);
                }
            });
        });
    </script>

2: Método de procesamiento en segundo plano de Java con framework (ssm)
     

Creamos un archivo html en el escritorio para acceder a nuestro código Java back-end y simular la separación de las páginas frontal y posterior, lo que provocará el problema de pérdida de sesión.

Cuando encontré este problema, el proceso de modificación fue el siguiente:
①: Use ajax para acceso directo sin realizar ninguna configuración, y aparece un error 403. La respuesta a la solicitud de verificación previa no pasa la verificación de control de acceso: No 'Access-Control-Allow-Origin "El encabezado está presente en el recurso solicitado. Por lo tanto, no se permite el acceso al origen 'nulo'. La respuesta tenía el código de estado HTTP 403. Obviamente, es entre dominios y el backend rechazó la solicitud.
②: Resolvemos el problema entre dominios agregando la anotación "@CrossOrigin(origins = "*", maxAge = 3600)" al controlador de backend para permitir todas las solicitudes, de modo que se pueda acceder a los métodos de backend.
③: Pero surge un nuevo problema: cada vez que solicitamos, siempre que se llame a request.getSession () en segundo plano (o la sesión se pase directamente como parámetro en springmvc), se generará una nueva sesión.
④: Cuando escribimos en java nativo, el front-end ajax tiene el atributo xhrFields: {withCredentials: true}, y también lo agregamos. Una prueba informó un error y probablemente se trataba de un problema entre dominios. emmmmm, ¿no está ya permitido el cross-domain?, ¿qué carajo es esto? Después de verificar la información, dice aproximadamente que la anotación "@CrossOrigin(origins = "*", maxAge = 3600)" solo se aplica para obtener solicitudes.
⑤: Nuestro Java nativo puede resolverlo, por lo que definitivamente es posible reemplazarlo con un marco. Después de buscar información, descubrimos que lo que necesitamos es configurar el encabezado de la respuesta cada vez. Según lo que se dice en línea, podemos interceptar cada solicitud y configurarla antes de ingresar al controlador, entonces el problema definitivamente se resolverá.

Método de escritura específico: ① Cree una nueva clase de interceptor para interceptar y configurar el encabezado de respuesta para cada solicitud. ②: Registre este interceptor en webxml ③: Preste atención al front-end ajax más "xhrFields: {withCredentials: true}"

拦截器类///
package com.xunshi.TimerEvent;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * @author liangpeng
 * @ClassName: AuthorityInterceptor拦截器,拦截每次请求
 * @Description: 前后端分离导致session不一致问题
 * @date 2018年10月18日  
 */
public class AuthorityInterceptor implements Filter {
    @Override
    public void destroy() {
    }
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        response.setContentType("textml;charset=UTF-8");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "0");
        response.setHeader("Access-Control-Allow-Headers",
                "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("XDomainRequestAllowed", "1");
        chain.doFilter(req, res);
    }
    @Override
    public void init(FilterConfig arg0) throws ServletException {
    }
}
///webxml配置,添加注册///
  <!--自定义拦截器,每次请求拦截,设置session跨域以及维持session配置  -->
  <filter>
       <filter-name>AuthorityInterceptor</filter-name>
       <filter-class>com.xunshi.TimerEvent.AuthorityInterceptor</filter-class>
    </filter>
    <filter-mapping>
       <filter-name>AuthorityInterceptor</filter-name>
       <url-pattern>/*</url-pattern>
    </filter-mapping>

Tres: procesamiento front-end de problemas de sesión del subprograma WeChat y modificación del código back-end

Los dos anteriores son para solicitudes ajax básicas. Para los miniprogramas WeChat, dado que los miniprogramas no pueden usar ajax para realizar solicitudes http, el manejo de problemas de sesión entre dominios de los miniprogramas WeChat es un poco diferente.
El método específico es: ① El backend devuelve el ID de sesión del miniprograma (preferiblemente cifrado) después del primer acceso al miniprograma, y ​​no es necesario configurar nada más. ②: Cada vez que el mini programa solicita un ID de sesión, el fondo de Java determinará automáticamente en qué cliente se basa el ID de sesión y encontrará la sesión correspondiente.
  

       wx.request({
            url: getApp().globalData.url + 'User/ShowOneCar/' + res.data.car_id,
            header: { "Cookie": "JSESSIONID=" + wx.getStorageSync("sessionID") },//带上这句话,sessionID是登陆后后端返回存在缓存里面的
            success: function (rr) {
              console.log(rr);
              if (rr.data.state) {
                that.setData({
                  carinfo: rr.data.thiscar
                });
              }
            }
          })

Para el problema de sesión del miniprograma, no es necesario crear un interceptor para configurarlo en segundo plano, es un poco confuso que ajax no funcione.
Sin embargo, existen más o menos problemas con el uso de sesiones para almacenar datos, incluidos problemas de seguridad y presión del servidor. Pero actualmente no conozco ninguna forma más sencilla de almacenar el estado de inicio de sesión del usuario, así que usémosla primero.

Supongo que te gusta

Origin blog.csdn.net/qq_22824481/article/details/81004051
Recomendado
Clasificación