我正在编写Golang API。 我对cors使用以下功能
1 2 3 4 5 6 | func ResponseWithJSON(w http.ResponseWriter, json []byte, code int) { w.Header().Set("Content-Type","application/json; charset=utf-8") w.Header().Set("Access-Control-Allow-Origin","*") w.WriteHeader(code) w.Write(json) } |
这使任何人都可以访问我的api。 我想将其限制为我的域名。 因为听起来更安全。 让我们称之为www.example.com
我可以将其更改为
1 | w.Header().Set("Access-Control-Allow-Origin","http://www.example.com") |
当网址为www.example.com而不是example.com时,这将允许我拨打电话
然后我可以将其更改为
1 | w.Header().Set("Access-Control-Allow-Origin","http://example.com") |
现在,我可以从example.com访问我的api,但不能从www.example.com访问
两者都不添加
都不是这样
1 | w.Header().Set("Access-Control-Allow-Origin","http://www.example.com,http://example.com") |
也没有这种方式
1 2 | w.Header().Set("Access-Control-Allow-Origin","http://www.example.com") w.Header().Set("Access-Control-Allow-Origin","http://example.com") |
那么,有没有办法让我获得请求的原产地? 这样我就可以动态允许域了吗? 我还有另一种解决这个问题的方法吗?
-
检查请求
host 标头并相应地提供响应。 - 我怎么做?你有什么例子吗?
- stackoverflow.com/q/42921567/251311
-
FWIW,
Header.Set() 不能多次设置相同的标头,因为它会替换以前设置的任何值。而是使用Header.Add() 。 - 不,那是行不通的。现在它说Access-Control-Allow-Origin标头包含多个值
-
如果两者都想尝试,请执行以下操作:
w.Header().Set("Access-Control-Allow-Origin","http:www.example.com http:example.com") -以空格作为分隔符,而不是逗号。根据此列表是用空格分隔的。 - 显然,逗号分隔的域和空格分隔的域都不起作用。与域列表匹配并将单个主机放在标头中仍然可以提高安全性,并且可以正常工作。回到@zerkms评论。看这里
- 是的,它仍然抱怨多个标题。我觉得那将是理想的解决方案。我终于在今天早上弄清楚了。我想要的信息位于代码前面的http.request对象中。假设您有一个对象r * http.Request,则可以像以下原点一样获取原点:= r.Header.Get(" Origin");所以我只是在每个api调用上返回一个空对象(如果它不是正确的来源)。
我发现Origin信息在http.Request对象中。 你可以用
1 | origin := r.Header.Get("Origin"); |
假设您有一个物体,例如
1 | r *http.Request |
如果对象来自example.com,则它将返回example.com,也将返回www.example.com。 然后,您可以测试它是否为这两个值之一,以进行身份验证。
Access-Control-Allow-Origin标头仅支持一个值,因此您必须检查Host请求标头,然后基于该标头做出决定:
1 2 3 4 5 6 7 8 9 10 | package main import"net/http" func myHandler(w http.ResponseWriter, r *http.Request) { switch host := r.Header.Get("Host"); host { case"www.example.com","example.com": w.Header().Set("Access-Control-Allow-Origin","http://"+host) } } |
并不是说主机头有时会被代理服务器更改。 然后,他们通常会添加X-Forwarded-Host标头或类似标头。 但是,仅检查您是否信任代理(以及如何建立信任是一个不同的问题)。
- 它的r.Header.Get(" Origin")不是主机
- 这些标题有不同的用途。 有关主机头的说明,请参见RFC7230。
- 我刚刚测试了它,Host返回了一个空字符串,origin返回了我要的内容,origin ...