关于 cors 跨域配置,不填 * 该怎么写?

2020-07-26 10:15:22 +08:00
 ChunkitAu

之前用 cors 跨域 Origin,Header,Method 填的都是*。

然后实习面试时问到这样写的安全性问题,我也知道不安全。。。

那这样字段不填 * 该怎么填呢?

现在配置:

	Origin : *
	Methods: GET, POST, PUT, DELETE, OPTIONS
	Header : X-Requested-With,Content-Type,Authorization,Origin,Accept

前端还是发生跨域问题,

前端请求 Header:

Content-Type:  'multipart/form-data' / 'application/x-www-form-urlencoded' /'application/json'

还有就是 origin 不填 * 的话,通过 nginx 转发,只填 nginx 的域名+端口? 那每个人都访问 nginx 的端口 然后转发到后端,那也是每个人可以访问,感觉和* 效果差不多(可能太菜了) 。。。

3697 次点击
所在节点    Java
13 条回复
yuzo555
2020-07-26 10:22:13 +08:00
前端会传给你 Origin 的,你判断下 Origin 是否合法,如果合法,输出客户端请求的 Origin 就行了
cxe2v
2020-07-26 10:31:03 +08:00
blessyou
2020-07-26 11:34:04 +08:00
维护一个 origin 白名单,如果来源 origin 存在于白名单返回 origin: 来源 origin
zqx
2020-07-26 11:55:32 +08:00
安卓一些浏览器没有按照标准实现响应头的值为*的情况,会导致请求失败
belin520
2020-07-26 12:44:07 +08:00
origin 作为一个变量,这个变量怎么定义取决于你的产品逻辑
* 就是 request 的 origin 是什么,这个变量就填什么
Juszoe
2020-07-26 13:55:02 +08:00
“只填 nginx 的域名和端口”和 * 效果可不一样。填*的话任何一个网站都能让用户请求你的服务器。限制 origin 只是为了防止跨域攻击
jinliming2
2020-07-26 14:00:59 +08:00
首先,浏览器发生跨域请求时分为两种,简单请求和需要预检的请求。

简单请求是指:
1. 请求方法仅限 GET 、POST 、HEAD 三种(你的 PUT 、DELETE 、OPTIONS 就不属于了)
2. 请求头仅限:(你的 X-Requested-With 、Authorization 就不属于了,Origin 本身就属于禁止头,是浏览器自动设置的,你不可以手动设置)
- Accept
- Accept-Language
- Content-Language
- Content-Type (仅限 application/x-www-form-urlencoded 、multipart/form-data 、text/plain 三者之一,你的 application/json 就不属于)
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
3. 没有在 XMLHttpRequest.upload 添加事件监听
4. POST 没有使用 ReadableStream

不满足简单请求的,就需要进行预检。

对于简单请求,服务器需要根据请求头中的 Origin 字段判断是否允许这个域来请求,允许的话,就在响应头中给出 Access-Control-Allow-Origin,值就和请求头的 Origin 一样就行。
简单请求只需要给 Access-Control-Allow-Origin 这一个头就行。

如果不是简单请求,那么在请求前,浏览器会自动发出一个 OPTIONS 预检请求,其中可能包含 Access-Control-Request-Method 和 /或 Access-Control-Request-Headers,指出申请使用的请求方法和携带的请求头。
服务器判断,是否允许,允许的话,就根据需求带上这些头:
Access-Control-Allow-Origin 指定允许的 Origin,和上面简单请求一样。
Access-Control-Allow-Methods 指定允许的请求方法,必须包含 Access-Control-Request-Method 中申请的值,否则跨域请求失败。
Access-Control-Allow-Headers 指定允许带的请求头,和 Access-Control-Allow-Methods 类似。
Access-Control-Expose-Headers 指定哪些响应头可以被访问,默认情况下,请求方只能访问到 Cache-Control 、Content-Language 、Content-Length 、Content-Type 、Expires 、Last-Modified 、Pragma 几个头,如果你的响应里带了其他头需要被请求者访问的话,需要加上这个头来指定。
如果服务器要求客户端自动携带身份信息( cookie 、Authorization 头、TLC 客户端证书),那么需要设置 Access-Control-Allow-Credentials: true 。否则请求不会自动带这些信息。
浏览器收到预检的响应之后,再根据响应里的授权,决定是跨域失败,还是继续发送跨域请求。
ChunkitAu
2020-07-26 15:03:12 +08:00
@yuzo555 @blessyou 怎么判断这个 orgin 是否合法呢 ? 例如我搭个博客,允许任何人访问,除了* ,有什么写法吗?
ChunkitAu
2020-07-26 15:07:12 +08:00
@jinliming2 感谢科普
liuzhaowei55
2020-07-26 17:24:35 +08:00
fumichael
2020-07-27 08:54:38 +08:00
跨域是浏览器端才会有,如果我用的是服务器端请求呢( Nginx 转发也算一种)
要“安全”,要通过接口鉴权去实现,比方说,需要登录或者带上 token 之类的
liuhuihao
2020-07-27 11:21:41 +08:00
@ChunkitAu 从请求的 header 中拿到 origin,放到返回的头的 Access-Control-Allow-Origin 即可满足你的 “例如我搭个博客,允许任何人访问” 需求
qwerthhusn
2020-07-27 14:20:40 +08:00
Access-Control-Allow-Headers 好像不能用* ,没效果

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

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

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

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

© 2021 V2EX