问题相关: fetch api 在浏览器内无法保存和发送 cookie
昨天碰到浏览器无法发送 cookie 的问题, 最后才发现是浏览器默认禁止第三方 cookie.
Chrome / Safari / iOS Safari 都是默认禁止三方 cookie 的.
好久之前做项目都是用 token 作为验证方式, 现在这个小项目后端使用 php5.6 seesion 形式记录用户会话.
那么问题来了, 现在浏览器禁止了三方 cookie 还有用 cookie 作为验证的可能吗? 不可能引导用户去手动开启 cookie 权限吧?
有啥好的替代方案? auth2?
ps. 小项目是 react 写的界面, 放到微信里的页面.
1
lhx2008 2018-12-25 08:52:35 +08:00 via Android
可能你对第三方 cookies 有什么误解,credientails 在跨域时是合法的,他只是把 cookies 时间弄错了。
|
3
shijianit 2018-12-25 08:55:01 +08:00
localStore
|
4
lqw3030 2018-12-25 08:57:54 +08:00 via iPhone
我用 jwt,证明“我是我”就可以了
|
5
FaiChou OP @lhx2008
前后端能做的我都做过: 前端 credentials: 'include', 后端 Access-Control-Allow-Credentials: true + Access-Control-Allow-Origin: http://localhost:3000 为了复现这个问题, 我在 GCP 上写了个简单的 php 验证就是不通过.. 当我把 cookie 权限打开 就正常了. |
7
ytmsdy 2018-12-25 08:59:14 +08:00
Http 里面的 Authorization 了解一下?
|
8
lhx2008 2018-12-25 09:00:56 +08:00 via Android
你可以访问下我博客 luan.ma 看看 v2.jinrishici.com 那个请求有没带 cookies 上去
|
10
Marstin 2018-12-25 09:03:54 +08:00
跨域请求的目的是干嘛呢,为什么要带 cookie,你这里既然都已经跨域了,cookie 带过去了,也能识别吗?
|
12
FaiChou OP |
13
FaiChou OP @lhx2008 很奇怪..
这是 chrome 里的, 我的跨域请求的 header 都会显示 *Provisional headers are shown*. 看不到 request header 里信息. 搜过网上的方案, 都解决不了 *Provisional headers are shown* 问题. 这是 Safari 里的, 请求会带上 cookie, 但所以请求都看过, 没有 set-cookie, 这个 request 里的 cookie 哪里来的呢? |
14
lhx2008 2018-12-25 09:20:04 +08:00 1
@FaiChou 确实是我错了,如果 chrome 设置了阻止第三方 cookies,确实是发不上的。但是我用过的浏览器好像默认都不阻止。
Provisional headers are shown 是 Chrome 的祖传 Bug,对于部分 HTTP2 的连接故意不显示,其实抓包你就发现挺正常的。 没有 cookies 访问的时候有 set-cookies,你可以清空那个域下面的 cookies,再访问一次可能可以看到。 所以,好一点解决方法可能是用 localstorage 了,我当初也是为这个事情绞尽脑汁。 不过好像有些统计 js 是用浏览器指纹的技术,甚至跨浏览器都可以跟踪用户,具体我也没研究出来 |
15
wuhuaji 2018-12-25 09:20:11 +08:00 1
你的 one.json 请求,返回的 cookie 没有设置 domain 属性,应该置为当前域名,也就是 luan.ma 。
部分响应头如下: server: nginx/1.15.5 date: Tue, 25 Dec 2018 01:17:17 GMT content-type: application/json;charset=UTF-8 set-cookie: X-User-Token=YAEAnG+2hPllOHE5Uwuxz8ZAzHqG7Pf/; Max-Age=7776000; Expires=Mon, 25 Mar 2019 01:17:17 GMT access-control-allow-origin: https://luan.ma access-control-allow-credentials: true |
17
FaiChou OP |
18
lhx2008 2018-12-25 09:34:34 +08:00
@FaiChou 是的,自从我升了 HTTP2 之后就不显示了,我开发的时候用 HTTP/1.1 啥事没有。但是如果不开阻止第三方的话,cookies 还是 set 到了
|
20
lhx2008 2018-12-25 09:39:40 +08:00
MDN 其实也有写,我当初看到中文版没翻译到。
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Requests_with_credentials Third-party cookies Note that cookies set in CORS responses are subject to normal third-party cookie policies. In the example above, the page is loaded from foo.example, but the cookie on line 22 is sent by bar.other, and would thus not be saved if the user has configured their browser to reject all third-party cookies. |
21
lhx2008 2018-12-25 09:42:33 +08:00
不过你可以研究下我网站上面那个 mta.qq.com 的请求,即使关闭了第三方 cookies,照样可以保持跟踪
|
22
wu67 2018-12-25 09:44:54 +08:00
额, 所以在 api 后面加?token=***不行吗
|
23
wuhuaji 2018-12-25 09:45:03 +08:00 1
@lhx2008 没明白你说的 domain 跨域完全不能用什么意思? cookie 是要设置 domain 的。
如前面有人所说,Provisional headers are shown 是 Chrome 的特色问题,不可尽信。你可用 Firefox 或者 Safire 看下。这里我看到响应头,是从请求中复制请求 [右键-copy-copy as curl ] ,然后拿到命令行中请求的。 |
25
lhx2008 2018-12-25 09:55:03 +08:00
|
26
lhx2008 2018-12-25 10:10:29 +08:00
js 在 pingjsqq.com
然后,核心代码是 a = "pvi"; window.localStorage ? localStorage.getItem(a) || sessionStorage.getItem(a) : (a = document.cookie.match(new RegExp("(?:^|;\\s)" + a + "=(.*?)(?:;\\s|$)"))) ? a[1] : ""; 先获取当前域下面的 localStorage,如果没有,获取 pingjsqq.com 域下面的 cookies 里面的 id,然后 set 到当前域的 localstorage,下次再读取当前域的 localstorage |
27
pubby 2018-12-25 10:22:02 +08:00 via Android
|
30
lhx2008 2018-12-25 10:32:31 +08:00
@FaiChou 他妙在用 js 域的 cookies 来存 token,兼容了浏览器不支持 localstorage 的情况,而且实现了跨域名追踪
|
32
lhx2008 2018-12-25 11:00:56 +08:00
我在 Github 上面看到一个更骚的操作,挂载一个 iframe,然后用 HTML5 的 postMessage 进行跨域通信
|
33
lhx2008 2018-12-25 11:01:06 +08:00
|
34
FaiChou OP @pubby @lhx2008
谢谢. 在 SO 上看到过一个~~答案~~问题 https://stackoverflow.com/questions/3342140/cross-domain-cookies |
35
lhx2008 2018-12-25 11:51:51 +08:00
我总结了一下,发了个帖子
https://www.v2ex.com/t/520756 |
36
EvilCult 2018-12-25 12:52:29 +08:00
jwt 了解一下
header 里加 Authorization |