LiteHub中间件之跨域访问CORS

原理

基本概念

在浏览器安全模型中,同源策略是最重要的安全基石。
一个“域”是由3个要素组成的:

  • 协议(如:http 或 https)
  • 主机(Host,如 www.example.*** 或 127.0.0.1)
  • 端口(Port,如 80 或 8080)

只要这三个完全一致,就是同源的。
例如

  • http://example.***:80 和 http://example.***:8080 是不同源
  • http://example.*** 和 https://example.*** 是不同源

下面是官网解释跨域的图解:

两种请求:浏览器将 CORS 请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

简单请求

按照 W3C 的 CORS 规范,只有完全满足「安全要求」的跨域请求,浏览器才会把它直接当成简单请求,直接发送给服务端,不需要先发 OPTIONS。
必须同时满足以下条件

  1. 请求方法必须是(GET/HEAD/POST)三者之一
  2. 请求头不能超出以下几个字段(A***ept、A***ept-Language、Content-Language、Content-Type)等
  3. Content-Type(如果存在的话),其值只能是application/x-www-form-urlencoded、multipart/form-data、text/plain

非简单请求(预检请求)

非简单请求是指那些对服务器有特殊要求的请求,例如:

  • 使用PUT或DELETE方法
  • 设置Content-Type为application/json
    即不满足简单请求的条件的都是预检请求(非简单请求)。

对于这类请求,浏览器会在正式通信前额外发送一次HTTP查询请求(即预检请求),这个过程叫做预检(Preflight)。该请求会确认:

  1. 当前网页域名是否在服务器的许可名单中
  2. 允许使用的HTTP方法和头信息字段
    只有在获得服务器肯定答复后,浏览器才会发出正式的XMLHttpRequest请求,否则将报错。

“预检请求”用的请求方法是 OPTIONS,表示这个请求是用来询问的。头信息里面,关键字是 Origin,表示请求来自哪个源。
除了 Origin 字段,“预检请求”的头信息包括两个特殊字段。
A***ess-Control-Request-Method:必须字段,列出浏览器的 CORS 请求会用到哪些 HTTP 方法;
A***ess-Control-Request-Headers:这个字段是一个逗号 , 分隔的字符串,指定浏览器 CORS 请求会额外发送的头信息字段,上面示例是 X-Custom-Header。

代码实现

CORS(Cross-Origin Resource Sharing,跨域资源共享)通过在响应头里加上一组特殊字段来告诉浏览器,这个资源允许被某些源访问。

服务器端Cors的关键配置

struct CorsConfig 
{
   
   
    std::vector<std::string> allowedOrigins;//允许哪些域名可以访问
    std::vector<std::string> allowedMethods; //允许哪些方法可以跨域调用
    std::vector<std::string> allowedHeaders; //允许前端请求里带哪些请求头
    bool allowCredentials = false; //不允许携带Cookie/Authorization header/TLS client cert 这类凭证信息
    int maxAge = 3600;             //浏览器缓存预检请求的最大时长, 1 小时内同样的跨域请求只会发送一次 OPTIONS,之后直接用缓存的结果
    
    static CorsConfig defaultConfig() 
    {
   
   
        CorsConfig config;
        config.allowedOrigins = {
   
   "*"}; //这里允许的是所有域名
        config.allowedMethods = {
   
   "GET", "POST", "PUT", "DELETE", "OPTIONS"}; //在预检请求(OPTIONS)的响应里告诉浏览器:后端接受哪些方法
        config.allowedHeaders = {
   
   "Content-Type", "Authorization"}; //允许前端带Content-Type(比如 application/json)和Authorization(携带JWT Token等)
        r
转载请说明出处内容投诉
CSS教程网 » LiteHub中间件之跨域访问CORS

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买