Nginx跨域请求处理

同源策略

同源策略是一个安全策略。同源,指的是协议,域名,端口相同。浏览器处于安全方面的考虑,只允许本域名下的接口交互,不同源的客户端脚本,在没有明确授权的情况下,不能读写对方的资源。

同源策略主要是基于如下可能的安全隐患:

  1. 用户访问www.mybank.com,登录并进行网银操作,这时cookie等资源都生成并存放在浏览器;
  2. 用户突然访问一个另一个网站;
  3. 该网站在页面中,拿到银行的cookie,比如用户名,登录token等,然后发起对www.mybank.com的操作;
  4. 若此时浏览器不对跨域做限制,并且银行也没有做响应的安全处理的话,那么用户的信息有可能就这么泄露了。

跨域简介

首先要理解跨域,跨域是指从一个域名的网页去请求另一个域名的资源。本质上对于此类请求,只要协议、域名、端口有任何一个的不同,就被当作是跨域,即都被当成不同源。
通常基于安全考虑,Nginx启用了同源策略,即限制了从同一个源加载的文档或脚本不能与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。
但若同一个公司内部存在多个不同的子域,子域之间需要互访,此时可通过跨域进行实现。跨域可通过JSONP和CORS进行实现。

注意:
如果是协议和端口造成的跨域问题"前端"是无法解决的;
在跨域实现上,仅仅是通过"URL的首部"来识别而不会根据域名对应的IP地址是否相同来判断。“URL的首部"可以理解为”“协议,域名和端口必须匹配”;
请求跨域并不是请求发不出去,请求可正常发出,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了

配置语法

语法:add_header name value [always];
默认值:——
可配置段:http, server, location, if in location
配置项释义:
Access-Control-Allow-Origin:配置 Access-Control-Allow-Origin 为 * 表示服务器可以接受所有的请求源(Origin),即接受所有跨域的请求,也可以指定一个确定的URL。
Access-Control-Allow-Headers:配置 Access-Control-Allow-Headers,代表允许在请求该地址的时候带上指定的请求头,例如:Content-Type,Authorization,使用逗号(,)拼接起来放在双引号(")中,可根据实际请求类型添加,可防止出现以下错误:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response。这个错误表示当前请求Content-Type的值不被支持。其实是因为发起了"application/json"的类型请求导致的。
Access-Control-Allow-Methods:配置 Access-Control-Allow-Methods,代表允许使用指定的方法请求该地址,常见的方法有:GET, POST, OPTIONS, PUT, PATCH, DELETE, HEAD。可防止出现以下错误:
Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
Access-Control-Max-Age:配置 Access-Control-Max-Age,代表着在 86400 秒之内不用请求该地址的时候 不需要再进行预检请求,也就是跨域缓存。
Access-Control-Allow-Credentials 'true':可选字段,为true表示允许发送Cookie。同时,发送时,必须设置XMLHttpRequest.withCredentials为true才有效,请求若服务器不允许浏览器发送,删除该字段即可。
return 204:给OPTIONS 添加 204 的返回,为了处理在发送POST请求时Nginx依然拒绝访问的错误,发送"预检请求"时,需要用到方法 OPTIONS,所以服务器需要允许该方法。
对于简单请求,如GET,只需要在HTTP Response后添加Access-Control-Allow-Origin。
对于非简单请求,比如POST、PUT、DELETE等,浏览器会分两次应答。第一次preflight(method: OPTIONS),主要验证来源是否合法,并返回允许的Header等。第二次才是真正的HTTP应答。所以服务器必须处理OPTIONS应答。
注意:如上的 add_header 最后都可以加上了 always,它表示不管返回状态码是多少都会使 add_header 生效,有些时候服务端可能会返回 4XX 的状态码,这时候如果少了 always 会导致 add_header 失效,从而导致浏览器报跨域错误。

配置示例

方案1 *:通配符,全部允许,存在安全隐患(不推荐)。

一旦启用本方法,表示任何域名皆可直接跨域请求:

server {
        ...
        location / {
            # 允许 所有头部 所有域 所有方法
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Headers' '*';
            add_header 'Access-Control-Allow-Methods' '*';
            # OPTIONS 直接返回204
            if ($request_method = 'OPTIONS') {
                return 204;
            }
        }
        ...
    }

方案2:多域名配置(推荐)

配置多个域名在map中 只有配置过的允许跨域:

map $http_origin $corsHost {
        default 0;
        "~https://zzzmh.cn" https://zzzmh.cn;
        "~https://chrome.zzzmh.cn" https://chrome.zzzmh.cn;
        "~https://bz.zzzmh.cn" https://bz.zzzmh.cn;
    }
    server {
        ...
        location / {
            # 允许 所有头部 所有$corsHost域 所有方法
            add_header 'Access-Control-Allow-Origin' $corsHost;
            add_header 'Access-Control-Allow-Headers' '*';
            add_header 'Access-Control-Allow-Methods' '*';
            # OPTIONS 直接返回204
            if ($request_method = 'OPTIONS') {
                return 204;
            }
        }
        ...
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值