Nginx配置码云token跨域请求

背景

  作者搭建个人博客的时候,用到第三方码云的认证(OAuth)服务,其中获取token的请求必须是post,如果在前端直接调用(https://gitee.com/oauth/token)的话,会出现跨域请求。最后作者在自己购买的vps上,安装了nginx,利用nginx的反向代理来跨域。同时为了提供给其他的人用,所以需要配置请求是可以直接跨域访问的。下面给出nginx中的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
location /token {
set $cors_origin "";
if ($http_origin ~* "^https://eillott.gitee.io$") {
set $cors_origin $http_origin;
}
add_header 'Access-Control-Allow-Methods' 'GET,OPTIONS,PUT,DELETE' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Origin' '$cors_origin' always;
add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,User-Agent,Keep-Alive,Content-Type,accept,origin,X-Requested-With' always;
if ($request_method = OPTIONS ) {
return 200;
}
proxy_pass https://gitee.com/oauth/token;
}

Http请求Option

  据RFC2616标准(现行的HTTP/1.1)得知,通常有以下8种方法:OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE和CONNECT。

其中OPTION的方法主要用途有两种

1. 获取服务器支持的HTTP请求方法;也是黑客经常使用的方法。

2. 用来检查服务器的性能。例如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个HTTP OPTIONS请求头,用以判断实际发送的请求是否安全。

Http跨域请求

  http跨域请求一般处理的方案有:1. 使用jsonp。2. 使用CORS(跨域资源共享)。

  jsonp就不介绍了,主要说下CORS,这是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源。而这种访问是被同源策略所禁止的。CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。当前浏览器基本都支持。

  1. 前端
  客户端使用XmlHttpRequest发起Ajax请求。

  2. 服务器端
  如果服务器端未做任何配置,则前端发起Ajax请求后,会得到CORS Access Deny,即跨域访问被拒绝。
  服务器端需要在增加response的Header:


Access-Control-Allow-Origin: ‘*’ 或者指定域名Access-Control-Allow-Origin: ‘https://eillott.gitee.io'

   Preflighted Requests 是CORS中一种透明服务器验证机制。预检请求首先需要向另外一个域名的资源发送一个 HTTP OPTIONS 请求头,其目的就是为了判断实际发送的请求是否是安全的。


下面的2种情况需要进行预检:
1. 简单请求,比如使用Content-Type 为 application/xml 或 text/xml 的 POST 请求。
2. 请求中设置自定义头,比如 X-JSON、X-MENGXIANHUI 等。

总结

   作者想让其他人也可以使用码云认证服务,就将自己nginx反向代理的请求设置为可以跨域访问,CORS跨域的时候,会先发送预检请求(OPTION方法发送),最开始作者没注意到这点(网上很少有讲到这点),导致一直是跨域访问被拒绝。知道作者加上下面配置,最后才成功的跨域访问。

1
2
3
if ($request_method = OPTIONS ) {
return 200;
}