服务端springboot2.x :localhost:8082
前端vue2.x :localhost:81
前后端的端口号不同,为跨域,导致前端访问后端时,每次访问都新生产一个sessionid。解决如下:
后端:
1.添加过滤器:
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() { } /** * 此过滤器只是处理跨域问题 * @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);// 允许指定域访问跨域资源(这里不能写*,*代表接受所有域名访问,如写*则下面一行代码无效。谨记) response.setheader("access-control-allow-credentials", "true");//true代表允许客户端携带cookie(此时origin值不能为“*”,只能为指定单一域名) response.setheader("access-control-allow-methods", "get, head, post, put, delete, trace, options, patch"); /// 允许浏览器在预检请求成功之后发送的实际请求方法名 response.setheader("access-control-allow-headers", "authorization,origin, x-requested-with, content-type, accept,access-token");// 允许浏览器发送的请求消息头 //response.setheader("access-control-max-age", "86400"); // 浏览器缓存预检请求结果时间,单位:秒 chain.dofilter(request,response); } @override public void init(filterconfig filterconfig) throws servletexception { } }
2. springboot2.配置过滤器时,启动类必须加上@servletcomponentscan才会加载过滤器
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入口 * mapperscan("com.nsoft.gkzp.**.dao")为扫描mapper, 所以dao下面的类就不需要添加@mapper注解了 * servletcomponentscan 添加了过滤器,故这里要添加@servletcomponentscan注解,spring才会扫描到过滤器(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); } /** * 在springboot整合vue前端时,vue使用url跳转时报404错误,此处代码解决此问题 * 参照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. spring-session 2.x
中 cookie
里面了samesite
,他默认值是 lax
samesite cookie 是用来防止csrf攻击,它有两个值:strict、lax
samesite = strict:意为严格模式,表明这个cookie在任何情况下都不可能作为第三方cookie;
samesite = lax :意为宽松模式,在get请求是可以作为第三方cookie,但是不能携带cookie进行跨域post访问(这就很蛋疼了,我们那个校验接口就是post请求)
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 中 cookie里面引入了samesite他默认值是 lax,
* samesite cookie 是用来防止csrf攻击,它有两个值:strict、lax
* samesite = strict:意为严格模式,表明这个cookie在任何情况下都不可能作为第三方cookie;
* samesite = lax:意为宽松模式,在get请求是可以作为第三方cookie,但是不能携带cookie进行跨域post访问
* 总结:前端请求到后台,每次session都不一样,每次都是新的会话,导致获取不到用户信息
*/
@configuration public class springsessionconfig { public springsessionconfig() { } @bean public cookieserializer httpsessionidresolver() { defaultcookieserializer cookieserializer = new defaultcookieserializer(); // 取消仅限同一站点设置 cookieserializer.setsamesite(null); return cookieserializer; } }
前端:
1.在 main.js (前端用axios)
import axios from 'axios'; axios.defaults.withcredentials=true;//让ajax携带cookie
用了1天半时间,改了很多次依然不行,后来发现是前端用了 proxy 代理,它本身也是已经处理了跨域问题,网上找的时候发现有的文章也用到这个了。但我这里就是不行。
我原来的代码:
1)写的注册页面:
2)全局配置如下:
main.js
// xenv 标记当前环境 true:开发环境 false:生产环境 const xenv = true; // 注册全局变量 vue.prototype.$global = { //contentpath 标记根路径,主要用于axios请求后端数据的url contentpath: xenv ? '/api/' : router.options.base };
(xenv设为true;所以 根路径contentpath的值必为‘/api/’ ,而‘/api/’ 在vue.config.js里配置为代理,如下。)
vue.config.js
devserver: { open: true, host: '0.0.0.0', port: 80, https: false, hotonly: false, before: app => { }, proxy: { // 配置跨域 '/api': { target: 'http://127.0.0.1:8082/', ws: true, changorigin: true, pathrewrite: { '^/api': '/' } } } },
2.不使用proxy代理,把根目录写死为'http://127.0.0.1:8082/',就成功了,修改如下:
main.js:
// xenv 标记当前环境 true:开发环境 false:生产环境 const xenv = true; // 注册全局变量 vue.prototype.$global = { // contentpath 标记根路径,主要用于axios请求后端数据的url // contentpath: xenv ? '/api/' : router.options.base contentpath: 'http://127.0.0.1:8082/' };
参照: