1、前言
在某次项目中遇见http使用iframe嵌套http时,登录一直失败,经过排查,是发送请求时cookie
未被携带过去,在响应头中的set-Cookie
报了这样一个警告⚠️:
This Set-Cookie header didn't specify a "SameSite" attribute and was defaulted to "SameSite=Lax," and was blocked because it come from a cross-site response which was not the response to a top-level navigation. The Set-Cookie had to have been set with "SameSite=None" to enable cross-site usage.
错误信息表明浏览器将 Cookie 的 SameSite
属性默认为 Lax
,这意味着 Cookie 只能在同源或顶层导航请求中发送,而不能在跨站请求中发送。为解决此问题,必须在 服务器端 设置 SameSite=None
和 Secure
属性。
问题到这,解决方案已经很明朗了:
proxy_cookie_path / "/; httponly; secure; SameSite=None";
-
SameSite=Strict
:仅允许同源请求携带 cookie。 -
SameSite=Lax
:允许某些跨站请求,但对于第三方请求可能会被阻止。 -
SameSite=None
:不限制跨站请求,但要求Secure=true
。
但是,需要注意的是,这样设置,如果 Secure=true
,则只有在 HTTPS
请求时,浏览器才会发送该 cookie
。若前端使用的是 HTTP
协议,cookie
将不会被发送。
不幸的是,客户强制要求使用http
,还是甲方牛,下辈子争取当甲方!
2、解决方案
2.1、改用https
被pass了
2.2、认证方式修改为token
开发时间长,又被pass了
2.3、服务端nginx代理
在A项目中将原来
iframe
的src
由具体的链接/IP地址修改为${location.origin}/kylin/xxx
,并在A项目的nginx进行配置转发/kylin
开头的请求
2.3.1、A项目修改iframe
和nginx
根据具体情况来,以下是笔者的配置
`${location.origin}/dasapi/overview`
# 排除特定路径
location ~* ^/kylin/(js|css|fonts)/ {
proxy_pass http://xxxxx;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# 重写 /kylin/xx 为 /xx
location ~* ^/kylin/(?!js|css|fonts|ace)(.*)$ {
rewrite ^/kylin/(.*)$ /$1 break;
proxy_pass http://xxxxx;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# 其他请求前缀为 /audit-apiv2/、/risk-platform/、/report-api/、/audit-report/
location ~* ^/(audit-apiv2|risk-platform|report-api|audit-report)/ {
proxy_pass http://xxxxx;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
2.3.2、B项目修改publicPath
- 首先,需要给静态资源加上一个前缀,比如:
/kylin
,修改vue.config.js
文件中的publicPath
,这样打包后的静态资源都会加上/kylin
这个前缀
module.exports = {
publicPath: '/dasapi',
lintOnSave: true,
assetsDir: './',
}
- 如此一来,我们在部署完时去访问,会报这些静态资源404的问题,那么还需要在nginx配置一下静态资源的代理,根据我的项目而言,是部署在
root
根目录下的webapp
文件夹下,那么添加的配置如下:
location /kylin/js/ {
alias /webapp/dist/js/;
}
location /kylin/css/ {
alias /webapp/dist/css/;
}
location /kylin/fonts/ {
alias /webapp/dist/fonts/;
}
- 如果到这步就部署了,那么大概率会遇到跳转到空白页面或者
error
页面的情况
2.3.3、router添加base路径
const router = new Router({
base: '/kylin'
})
这个给整个url
加统一的前缀,因为iframe
的src
值以该base路径为前缀,在进入到我们项目的beforeEach时,第一次中的to.path
仍然是/kylin/xxx
,如果没有加base
路径的话,将无法匹配,页面将导致空白或者到error
页面
到此结束。