V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
YJi
V2EX  ›  程序员

借着首页在讨论跨域,一个运维朋友教我写的配置合适不?

  •  
  •   YJi · 58 天前 · 2279 次点击
    这是一个创建于 58 天前的主题,其中的信息可能已经有所发展或是发生改变。
    add_header 'Access-Control-Allow-Origin' $http_origin;
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
    if ($request_method = 'OPTIONS') {
    add_header 'Access-Control-Max-Age' 1728000;
    add_header 'Content-Type' 'text/plain; charset=utf-8';
    add_header 'Content-Length' 0;
    return 204;
    }

    这么配置有没有啥问题?
    21 条回复    2024-07-12 13:02:05 +08:00
    magicZ
        1
    magicZ  
       58 天前
    前端网站地址: http://localhost:8080
    服务端网址: http://localhost:59200
    # nginx 跨域配置
    server {
    listen 22222;
    server_name localhost;
    location / {
    add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
    add_header Access-Control-Allow-Headers '*';
    add_header Access-Control-Allow-Methods '*';
    add_header Access-Control-Allow-Credentials 'true';
    if ($request_method = 'OPTIONS') {
    return 204;
    }
    proxy_pass http://localhost:59200;
    }
    }

    来源 https://mp.weixin.qq.com/s/VzWlJ8laLn8AI-JoiDepug
    raviscioniemeche
        2
    raviscioniemeche  
       58 天前
    比较合理 除了头部那里
    chenliangngng
        3
    chenliangngng  
       58 天前
    没啥问题,但是只限定自家公司产品,有的配置是专有的
    salmon5
        5
    salmon5  
       58 天前
    合理个锤子,add_header 指令不能放在 if 里,要用 map 。
    coolcoffee
        6
    coolcoffee  
       58 天前   ❤️ 1
    如果不是非必要,最好从后端 web server 框架里面加 CORS ,不然很容易出现双 CORS 响应头反而导致失效。
    salmon5
        7
    salmon5  
       58 天前
    @coolcoffee #6 这样是最规范和合理的,谁的问题谁解决。小作坊公司一般是加到 nginx ,省事。
    ilvsxk
        8
    ilvsxk  
       58 天前   ❤️ 1
    @magicZ #1

    在响应附带身份凭证的请求时(通常是 Cookie ):

    服务器不能将 Access-Control-Allow-Headers 的值设为通配符“*”,而应将其设置为标头名称的列表,如:Access-Control-Allow-Headers: X-PINGOTHER, Content-Type

    服务器不能将 Access-Control-Allow-Methods 的值设为通配符“*”,而应将其设置为特定请求方法名称的列表,如:Access-Control-Allow-Methods: POST, GET
    vueli
        9
    vueli  
       58 天前
    就我所知,最好的跨域解决方案就是前端 nginx 开一个反向代理
    mjollnirray
        10
    mjollnirray  
       58 天前
    if is evil
    mjollnirray
        11
    mjollnirray  
       58 天前   ❤️ 1
    server {
    listen 22222;
    server_name localhost;
    location / {
    add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
    add_header Access-Control-Allow-Headers '*';
    add_header Access-Control-Allow-Methods '*';
    add_header Access-Control-Allow-Credentials 'true';
    if ($request_method = 'OPTIONS') {
    add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
    add_header Access-Control-Allow-Headers '*';
    add_header Access-Control-Allow-Methods '*';
    add_header Access-Control-Allow-Credentials 'true';
    return 204;
    }
    proxy_pass http://localhost:59200;
    }
    }
    concernedz
        12
    concernedz  
       58 天前   ❤️ 2
    # 跨域 START
    if ($http_origin !~* "^( http://localhost:1617|http://localhost:8080)$") {
    return 403;
    }

    add_header Access-Control-Allow-Origin $http_origin always;
    add_header Access-Control-Allow-Methods 'GET,POST,PATCH,PUT,DELETE,OPTIONS';
    add_header Access-Control-Allow-Headers 'Authori-zation,Authorization,Content-Type,If-Match,If-Modified-Since,If-None-Match,If-Unmodified-Since,X-Requested-With,Form-type,Cb-lang,Invalid-zation';
    add_header Access-Control-Allow-Credentials 'true';
    add_header Access-Control-Max-Age '1728000';

    if ($request_method = 'OPTIONS') {
    return 204;
    }
    # 跨域 END

    v2 不支持 md 写法吗
    cat
        13
    cat  
       58 天前   ❤️ 1
    @concernedz 评论不支持 markdown
    ragnaroks
        14
    ragnaroks  
       58 天前
    以我个人了解,只要 Access-Control-Allow-Origin 的值不是 * 就已经合格了
    ETiV
        15
    ETiV  
       58 天前   ❤️ 1
    看你想干啥……本地开发随便写写,线上这么写有问题。。。

    ★ Allow-Origin 赋值成 $http_origin ,就等价于 allow *
      origin 是请求时携带的网页 URL ,现在这么配,是来者不拒的意思,或者像 #12 那样提前判断下。

    ★ 应该仅在必要的 Method & URL 上加 header 字段,而不是直接写在 server {…} 或 location / {…} 这样粗暴。
     我们为了减少静态资源的 overhead 流量会给 CDN 单独买个域名,就是为了在请求和响应期间减少 header 所携带的内容。CORS 这种功能性的 header 应该仅在必要时出现。

    ★ 后端框架也需要注意的一点
     我遇到过一个网站,虽然有 CORS 策略阻止我干坏事儿,但是他们 jsonp 是开着的。我觉得是后端框架的锅,默认开启了 jsonp 的特性,URL 追加个 ?callback=jsonp_xxxx 还是能从前端跨域拿到对方的数据…
    yuanxiaosong
        16
    yuanxiaosong  
       57 天前
    @coolcoffee 正常正好相反,一个后端 API 可能对应 n 个业务线,每个业务线又有 n 个产品,鬼才知道前端用的什么域名,所以我们的操作是使用 proxy_hide_header ,不管后端服务设置什么跨域全部丢弃掉。
    yuanxiaosong
        17
    yuanxiaosong  
       57 天前
    @salmon5 我倒是觉得小公司才在后端服务里面写跨域,一般来说环境有开发/测试/预发布/生产(蓝/绿)/演示环境等,并且一个公共服务 API 会被多个产品调用,每个产品一级域名都不一样,有些产品客户还有私有化部署需求,还没考虑私有化部署需求,难道让后端把所有域名都收集好写到代码/配置里面,每次新增一个域名都改一次后端服务?众所周知,Access-Control-Allow-Origin 只能是单个域名或者*,如果一个 api 对应多个不同一级域名,代码还要
    if (ALLOW_ORIGINS.contains(requestDomain)) {
    resp.addHeader("Access-Control-Allow-Origin", requestDomain);
    }
    这种写法,不难受么?
    salmon5
        18
    salmon5  
       57 天前
    @yuanxiaosong #抽出来,可配置的,跨域是业务问题,业务来解决。
    否则就会前端、后端、运维 3 方扯皮。本来就是后端自己的事情。
    salmon5
        19
    salmon5  
       57 天前
    @yuanxiaosong 规模大了,业务网关上配置也行。
    coolcoffee
        20
    coolcoffee  
       57 天前
    @yuanxiaosong 虽然现在 cookie 不是很常见了,但是如果需要能支持 cookie 那还是需要单个域名,那这个只有交给业务框架的 web server 来处理才行。

    我的做法是一个公司的对外顶级域名毕竟还是可枚举,我知道的大部分框架都是可以支持回调方法来返回一个 true or false 来放行,那么回调里面就可以改成匹配顶级域名的形式来放行。
    ysc3839
        21
    ysc3839  
       57 天前 via Android   ❤️ 1
    @salmon5 add_header 可以写 if 里,但是 if 要在 location 里。
    https://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1062 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 23:28 · PVG 07:28 · LAX 16:28 · JFK 19:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.