type
Post
status
Published
date
Feb 2, 2022
slug
summary
withCredentials: true 开启后仍需要设置 SameSite=None ,并开启 Tomcat 的 HTTPS 支持
tags
项目方案
category
技术分享
icon
password
跨域解决方案
跨域请求访问问题的后端Cros三种解决方案:
- 局部:@CrossOrigin注解的origins 属性设置允许跨域访问的 URL
设置后响应头上会添加上对应允许跨域的信息
- 全局:SpringMVC 下的配置类实现
WebMvcConfigurer接口,并重写addCorsMappings方法
- 全局:全局过滤器类,拦截到响应后,给响应设置允许跨域相关的响应头
- 允许跨域访问的来源:Access-Control-Allow-Origin
- 不能设置为*,否则导致Access-Control-Allow-Credentials = true 的响应头失效
这样就解决了跨域访问问题,但遇到了新的问题:前端无法携带 Cookie 来访问接口
携带 Cookie
- 前端需要加上
withCredentials: true属性,如果是用 vue axios发送的请求,需要在 main.js中配置
- 后端在响应头中,需要加上:
response.setHeader("Access-Control-Allow-Credentials", "true");
查询搜索引擎和有关文档,了解到和 cookie 的 SameSite 属性有关
SameSite 属性
浏览器的 Cookie 信息可以用来保存登录信息来保持登录验证状态,并且随着请求自动发送到服务器,这就给了其他站点发起CSRF攻击和用户追踪的机会
cookie的SameSite属性,就是用来限制第三方网站的cookie发送机制
三种取值:
Set-Cookie: name=value;** SameSite=xxx;**
- Strict 严格模式:完全禁止跨站请求携带 cookie
- Lax 宽松模式:允许导航到第三方网站时携带,例如<a>跳转,<form>表单的提交
- None 显式关闭 SameSite 模式,但同时,必须加上secure参数,即:
Set-Cookie: name=value; SameSite=None; Secure;
加上 Secure 后,cookie只会在HTTPS中发送,也就是说只有在 https 协议下 cookie 发送才有效
开启Secure 的方法是在 web.xml 中加上:
<session-config> <cookie-config> <secure>true</secure> </cookie-config> </session-config>
现在的问题就剩下:
- 如何开启SameSite=None 这个属性
- 如何开启 https 访问
操作步骤
查询相关资料得知:SameSite是Cookie在新的 web 标准中的属性,Servlet 4.0规范不支持SameSite cookie属性,servlet.http.Cookie 库中没有设置SameSite属性的方法,而在 HttpSession 中JSESSIONID的默认 Cookie中,虽然存在server.servlet.session.cookie.secure的配置项,但没有提供对应的修改方法,所以只能通过修改容器配置,来设置SameSite属性
- tomcat 下conf/context.xml 新增标签:
<CookieProcessor sameSiteCookies="None" />
- 使用 jdk 提供的密钥生成工具生成密钥:

keytool -genkeypair -alias "tomcat" -keyalg "RSA" -keystore "apache-tomcat-7.0.77\bin\tomcat.keystore"
输入相关信息和一个密钥口令,会在指定目录(一般指定在 tomcat/bin下)生成一个密钥文件
修改server.xml 文件:
原: <!-- <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeystoreFile="conf/localhost-rsa.jks" type="RSA" /> </SSLHostConfig> </Connector> --> 现: <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="/Users/admin/apache-tomcat-8.5.69/apache-tomcat-8.5.69/bin/tomcat.keystore" keystorePass="jjbbkk" />
如果在 SpringBoot 下的内置 tomcat 中就更加简单,生成密钥后移动到 resourses 目录下,进行ssl 的配置 :
server.port=8888 server.ssl.key-store=classpath:keystore.p12 server.ssl.key-store-password=123456(此处密码为第一步中创建.p12文件时你输入的口令) server.ssl.keyStoreType=PKCS12 server.ssl.keyAlias=tomcat
参考资料
Relate Posts
