springboot+vue2.x Solves session Cross-domain Failure Problem

Keywords: Java Session Vue axios Spring

Server SpringBoot 2.x: localhost:8082

Front-end Vue2.x: localhost:81

The port numbers of the front and back end are different, which is cross-domain, resulting in a new session ID generated for each visit when the front end accesses the back end. The solutions are as follows:

 

Backend:

1. Add filters:

package com.nsoft.gkzp.syscore.config.filter;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter(urlPatterns = "/*", filterName = "corsFilter")
public class CorsFilter implements Filter {

    final private static Logger logger = LogManager.getLogger(CorsFilter.class);
    @Override
    public void destroy() {
    }
    /**
     * This filter only deals with cross-domain issues
     * @param servletRequest
     * @param servletResponse
     * @param chain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String origin = request.getHeader("Origin");
        if(origin == null) {
            origin = request.getHeader("Referer");
        }
        response.setHeader("Access-Control-Allow-Origin", origin);// Allow access to cross-domain resources for specified domains(It can't be written here.*,*Representatives receive access to all domain names, such as Write*The next line of code is invalid. Keep in mind)
        response.setHeader("Access-Control-Allow-Credentials", "true");//true Representatives allow clients to carry cookie(here origin Value cannot be“*",Can only specify a single domain name)
        response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH"); /// Actual request method name that allows browsers to send after a successful check request
        response.setHeader("Access-Control-Allow-Headers", "Authorization,Origin, X-Requested-With, Content-Type, Accept,Access-Token");// Request headers that allow browsers to send
        //response.setHeader("Access-Control-Max-Age", "86400");            // Browser Cache Preview Request Result Time,Company:second

        chain.doFilter(request,response);
    }
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }


}

2. springboot2. When configuring filters, the startup class must add @ServletComponentScan to load the filters

package com.nsoft.gkzp;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**
 * springboot Entrance
 * MapperScan("com.nsoft.gkzp.**.dao")To scan mapper, the class under dao does not need to add the @mapper annotation
 * ServletComponentScan  A filter has been added, so the @Servlet ComponentScan annotation is added here to scan spring to the filter (eg:com.nsoft.gkzp.syscore.config.filter.CorsFilter)
 */
@SpringBootApplication
@ServletComponentScan
@MapperScan("com.nsoft.gkzp.**.dao")
public class GzyGkzpApplication {

    public static void main(String[] args) {
        SpringApplication.run(GzyGkzpApplication.class, args);
    }


    /**
     * When springboot integrates the front end of vue, Vue uses url jump time 404 error. This code solves this problem.
     * Refer to https://blog.csdn.net/Mr_EvanChen/article/details/83625082.
     */
    @Bean
    public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer(){
        return factory -> {
            ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/index.html");
            factory.addErrorPages(error404Page);
        };
    }

}

3. In spring-session 2.x, Cookie contains SameSite, whose default value is Lax.

SameSite Cookie is used to prevent CSRF attacks. It has two values: Strict, Lax
SameSite = Strict: Means a strict pattern, indicating that this cookie cannot be a third-party cookie under any circumstances;
SameSite = Lax: This means relaxed mode. A get request can be used as a third-party cookie, but can't carry cookies for cross-domain post access (it's a pain, our checking interface is a POST request).

package com.nsoft.gkzp.syscore.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;

/**
* https://www.cnblogs.com/hujinshui/p/11025848.html
* spring-session 2.x In Cookie, SameSite is introduced. Its default value is Lax.
* SameSite Cookie It is used to prevent CSRF attacks. It has two values: Strict and Lax.
* SameSite = Strict: It means strict mode, which means that this cookie can not be used as a third-party cookie under any circumstances.
* SameSite = Lax: In a relaxed mode, a get request can be used as a third-party cookie, but cannot carry cookies for cross-domain post access.
* Summary: Front-end requests to the background, each session is different, each session is a new session, resulting in no access to user information
*/
@Configuration public class SpringSessionConfig { public SpringSessionConfig() { } @Bean public CookieSerializer httpSessionIdResolver() { DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer(); // Cancel the same site settings only cookieSerializer.setSameSite(null); return cookieSerializer; } }

 

Front end:

1. In main.js (front-end axios)

import axios from 'axios';
axios.defaults.withCredentials=true;//Let ajax carry cookie s

 

After a day and a half, I changed many times, but I still can't. Later, I found that proxy agent was used in the front end. It has also dealt with cross-domain problems. When I searched online, I found that some articles also used this. But I just can't do it here.

My original code:

1) Write the registration page:

 

2) The global configuration is as follows:

main.js

// xenv tags current environment true: development environment false:production environment
const xenv = true;
// Register global variables
Vue.prototype.$global = {
   //contentPath tags the root path, mainly for URLs that axios request back-end data
   contentPath: xenv ? '/api/' : router.options.base  
};

(xenv is set to true; so the value of the root path contentPath must be'/ api /', and'/ api /'is configured as a proxy in vue.config.js, as follows. )

vue.config.js

  devServer: {
    open: true,
    host: '0.0.0.0',
    port: 80,
    https: false,
    hotOnly: false,
    before: app => {
    },
    proxy: {
      // Configuration across domains
      '/api': {
        target: 'http://127.0.0.1:8082/',
        ws: true,
        changOrigin: true,
        pathRewrite: {
          '^/api': '/'
        }
      }
    }
  },

 

2. Without using proxy proxy proxy proxy proxy proxy proxy proxy proxy proxy, the root directory is written to'http://127.0.0.1:8082/'.

main.js:

// xenv tags current environment true: development environment false:production environment
const xenv = true;
// Register global variables
Vue.prototype.$global = {
  // contentPath tags the root path, mainly for URLs that axios request back-end data
  // contentPath: xenv ? '/api/' : router.options.base
  contentPath:  'http://127.0.0.1:8082/'
};

 

 

Reference:

https://www.cnblogs.com/zimublog/p/10786110.html

https://blog.csdn.net/qq_17555933/article/details/92017890

Posted by jumphopper on Wed, 09 Oct 2019 17:57:01 -0700