前后端分离的项目中(跨域请求 api), 如何正确使用 cookie 作为验证?

2018-12-25 08:47:57 +08:00
 FaiChou

问题相关: fetch api 在浏览器内无法保存和发送 cookie

昨天碰到浏览器无法发送 cookie 的问题, 最后才发现是浏览器默认禁止第三方 cookie.

Chrome / Safari / iOS Safari 都是默认禁止三方 cookie 的.

好久之前做项目都是用 token 作为验证方式, 现在这个小项目后端使用 php5.6 seesion 形式记录用户会话.

那么问题来了, 现在浏览器禁止了三方 cookie 还有用 cookie 作为验证的可能吗? 不可能引导用户去手动开启 cookie 权限吧?

有啥好的替代方案? auth2?

ps. 小项目是 react 写的界面, 放到微信里的页面.

8242 次点击
所在节点    前端开发
36 条回复
lhx2008
2018-12-25 08:52:35 +08:00
可能你对第三方 cookies 有什么误解,credientails 在跨域时是合法的,他只是把 cookies 时间弄错了。
FaiChou
2018-12-25 08:54:35 +08:00
@lhx2008 cookie 时间是没错的, "GMT", 我手动开启了三方 cookie 权限 是可以正常请求的.
shijianit
2018-12-25 08:55:01 +08:00
localStore
lqw3030
2018-12-25 08:57:54 +08:00
我用 jwt,证明“我是我”就可以了
FaiChou
2018-12-25 08:58:05 +08:00
@lhx2008

前后端能做的我都做过:

前端 credentials: 'include',
后端 Access-Control-Allow-Credentials: true + Access-Control-Allow-Origin: http://localhost:3000

为了复现这个问题, 我在 GCP 上写了个简单的 php



验证就是不通过..

当我把 cookie 权限打开 就正常了.
lhx2008
2018-12-25 08:59:04 +08:00
@FaiChou 那就不太清楚了,我的 chrome71 和 firefox 都没问题
ytmsdy
2018-12-25 08:59:14 +08:00
Http 里面的 Authorization 了解一下?
lhx2008
2018-12-25 09:00:56 +08:00
你可以访问下我博客 luan.ma 看看 v2.jinrishici.com 那个请求有没带 cookies 上去
Desiree
2018-12-25 09:03:02 +08:00
@lhx2008 好奇问下,大哥你这个博客是用什么搭的,挺好看的
Marstin
2018-12-25 09:03:54 +08:00
跨域请求的目的是干嘛呢,为什么要带 cookie,你这里既然都已经跨域了,cookie 带过去了,也能识别吗?
lhx2008
2018-12-25 09:08:19 +08:00
@Desiree 博客底下有,hexo 和 aircloud 主题
FaiChou
2018-12-25 09:09:10 +08:00
@lhx2008 好的 等我验证下.


@Marstin 「既然都已经跨域了,cookie 带过去了,也能识别吗」没明白这句话. 我认为浏览器会自动处理某域下的 cookie
FaiChou
2018-12-25 09:14:38 +08:00
@lhx2008 很奇怪..



这是 chrome 里的, 我的跨域请求的 header 都会显示 *Provisional headers are shown*. 看不到 request header 里信息. 搜过网上的方案, 都解决不了 *Provisional headers are shown* 问题.



这是 Safari 里的, 请求会带上 cookie, 但所以请求都看过, 没有 set-cookie, 这个 request 里的 cookie 哪里来的呢?
lhx2008
2018-12-25 09:20:04 +08:00
@FaiChou 确实是我错了,如果 chrome 设置了阻止第三方 cookies,确实是发不上的。但是我用过的浏览器好像默认都不阻止。
Provisional headers are shown 是 Chrome 的祖传 Bug,对于部分 HTTP2 的连接故意不显示,其实抓包你就发现挺正常的。
没有 cookies 访问的时候有 set-cookies,你可以清空那个域下面的 cookies,再访问一次可能可以看到。
所以,好一点解决方法可能是用 localstorage 了,我当初也是为这个事情绞尽脑汁。
不过好像有些统计 js 是用浏览器指纹的技术,甚至跨浏览器都可以跟踪用户,具体我也没研究出来
wuhuaji
2018-12-25 09:20:11 +08:00
你的 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
lhx2008
2018-12-25 09:22:58 +08:00
@wuhuaji 我想要做跨站保持同一个 cookies,以为这个是一个公开的 API,这个方法好像大多数时候是凑效的
FaiChou
2018-12-25 09:28:34 +08:00
@lhx2008 谢谢, 我的浏览器默认都是禁止, 在网上看到过好像因为隐私问题被欧盟一直追究, 所以很多浏览器都是默认禁止的

在 Safari 中是 prevent cross-site tracking



@wuhuaji 请问你是在 chrome 中看到这些信息的吗? 我的跨域请求在 chrome 中都看不到 set-cookie 字段. 我用 Charles 抓包关掉代理 luan.ma 就访问不了了

lhx2008
2018-12-25 09:34:34 +08:00
@FaiChou 是的,自从我升了 HTTP2 之后就不显示了,我开发的时候用 HTTP/1.1 啥事没有。但是如果不开阻止第三方的话,cookies 还是 set 到了
lhx2008
2018-12-25 09:35:17 +08:00
@wuhuaji domain 好像完全跨域是不能用的,我也不太清楚
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.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/520669

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX