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

nginx 302 转发如何携带原请求的 head

  •  1
     
  •   hello826 · 216 天前 · 2678 次点击
    这是一个创建于 216 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景是有一台内网的 nginx 不能反问外网,但是有个请求需要转发到外网的一个地址,目前通过 return 302 实现了 但是 302 的时候无法携带 head ,试了

    proxy_set_header X-Original-userAccount $http_x_original_userAccount

    proxy_set_header X-Original-user-account $http_x_original_user_account

    也还是取不到头,服务的是通过 request.getHeader("userAccount")取的 具体 nginx 配置如下,有无运维大佬能指点一下

    localtion /test{

    proxy_set_header X-Original-userAccount $http_x_original_userAccount;
    
    proxy_set_header X-Original-user-account $http_x_original_user_account;
    
    return 302 http://10.14.13.12/test?$args;
    

    }

    29 条回复
    nodejx
        1
    nodejx  
       216 天前
    location /test {
    proxy_set_header X-Original-userAccount $http_x_original_userAccount;
    proxy_set_header X-Original-user-account $http_x_original_user_account;
    proxy_pass http://10.14.13.12/test?$args;
    }
    AloneHero
        2
    AloneHero  
       216 天前 via Android
    重定向应该带不了 header
    Puteulanus
        3
    Puteulanus  
       216 天前
    307 和 308 ?
    caola
        4
    caola  
       216 天前
    307 转发也不行吗?
    xiri
        5
    xiri  
       216 天前
    301 、302 重定向都是服务端告诉客户端重新对一个新地址发起请求,当前会话直接是结束了,没法影响客户端下一次重新发起请求中的内容的,感觉你需要的是反向代理而不是重定向?
    icaolei
        6
    icaolei  
       216 天前
    用 rewrite 试试呢?
    ETiV
        7
    ETiV  
       216 天前 via iPhone
    302 都能带 header ,网络安全就不存在了…

    你需要做的是在这个不能访问外网的 nginx 前面再加一个能访问的,对于你提到 302 的这个请求 proxy pass 到外网去,其余的 pass 给正文提到的 nginx
    neighbads
        8
    neighbads  
       216 天前
    换到 get 参数上,放到 url 里。外网服务改一下
    yinmin
        9
    yinmin  
       216 天前 via iPhone
    这题有实战经验,安全的解法是:return 200 带一个 html 页面,页面里有一个 form ,post 参数到外网 url ,然后外网服务获取 post 参数。
    leonshaw
        10
    leonshaw  
       216 天前 via Android
    CORS
    zliea
        11
    zliea  
       216 天前
    301 ,302 重发请求带参数不是客户端该干的事么?
    sagaxu
        12
    sagaxu  
       216 天前
    标准答案 307

    The only difference between 307 and 302 is that 307 guarantees that the method and the body will not be changed when the redirected request is made.
    F7TsdQL45E0jmoiG
        13
    F7TsdQL45E0jmoiG  
       216 天前
    按照 http 协议规范,307 可以
    siweipancc
        14
    siweipancc  
       216 天前 via iPhone
    location 由请求方处理,一般客户端都会处理这个
    hello826
        15
    hello826  
    OP
       216 天前
    试了 307 也不行,还是取不到头,这两种都试了

    location /test {

    proxy_set_header X-Original-userAccount $http_x_original_userAccount;

    proxy_set_header X-Original-user-account $http_x_original_user_account;

    return 307 http://10.14.13.12/test?$args;
    }

    location /test {

    return 307 http://10.14.13.12/test?$args;

    }

    目前想到的方法是走服务端转发,服务端所在的机器可以访问外网,nginx 不能访问外网
    jifengg
        16
    jifengg  
       216 天前
    proxy_set_header 是你用 proxy_pass 时携带给代理地址的,不是返回给客户端的,所以你应该用 add_header
    注:没实验过,请楼主自行实验
    hello826
        17
    hello826  
    OP
       216 天前
    @jifengg add_header 也试了,不行,看来这条路是走不通
    add_header X-Original-userAccount $http_x_original_userAccount always;
    add_header X-Original-user-account $http_x_original_user_account always;
    add_header X-Original-UserAccount $http_useraccount always;
    killva4624
        18
    killva4624  
       216 天前
    add_header 只是在这个 302 返回上加 header ,和客户端重定向之后的新请求没有关系吧。
    可以换个思路,需要访问外网的请求,代理转发到另外一个出口代理。
    superrichman
        19
    superrichman  
       216 天前
    @hello826 #15 客户端在处理 307 重定向,默认只会读取返回的 Location 头信息并更新,然后保持原有的 header 和 body 信息向新的位置发起请求。在 307 响应中服务端设置的其他头信息通常不会被客户端处理。
    F7TsdQL45E0jmoiG
        20
    F7TsdQL45E0jmoiG  
       216 天前
    add_header 处理的是响应头,应该是发请求头,请求头在客户端发起时设置
    jifengg
        21
    jifengg  
       216 天前
    试了下,启动一个 http 服务( 8081 端口)打印原始 header 和 body ,并用 nginx ( 80 端口)配置 307 到这个服务
    location =/test307 {
    return 307 http://127.0.0.1:8081/?redirtby=nginx;
    }

    客户端发起请求时携带 header

    curl "127.1/test307" -iL --header "h1:v1" --header "X-Original-user-account:jifeng"

    在 http 服务中是能收到这两个 header 的。

    在 nginx 中 add_header 没用。必须是客户端携带的 header 。

    另外,你要确保你取 header 的那个代码是正确的。
    yinmin
        22
    yinmin  
       216 天前
    nginx 加了是 response header ,307 是指 request header ,不是一个东西。
    coolloves
        23
    coolloves  
       216 天前
    cookie 试试?
    设置 cookie 时指定了 Domain 属性为.test.com
    比如你内网你解析一个 a.test.com,然后重定向到 b.test.com,这时候,cookie 可以 share 的吧?
    proxytoworld
        24
    proxytoworld  
       216 天前
    为什么不反代呢
    feixiangcode
        25
    feixiangcode  
       216 天前
    302 是服务器给终端发送一个 HTTP 的状态码,具体的跳转行为是终端拿到 Location 自己做的跳转。服务器只发状态码,跟数据无关。
    dyllen
        26
    dyllen  
       216 天前
    你这配置明显就是错的,用的 proxy_set_header 指令,又 return 302 ,302 又不是转发请求,ng 服务器访问不了外网,就不能用它来代理访问外网的请求。
    NeedI09in
        27
    NeedI09in  
       216 天前
    1.通过返回的 Location 字段携带信息,例如 Location: /test?data=1
    2.放在客户端 cookie 里
    http 协议规范里好像没有与转发请求头相关的,所以用 cookie 比较适合你的方案。
    jpyl0423
        28
    jpyl0423  
       216 天前
    用反代能解决吧
    deorth
        29
    deorth  
       215 天前 via Android
    要在脑子里打开
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3114 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 12:37 · PVG 20:37 · LAX 04:37 · JFK 07:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.