部署  HTTP Origin header didn't match request.base_url Nginx 配置 Origin

helapu · 2017年07月05日 · 最后由 lijunwei 回复于 2022年02月07日 · 8353 次阅读

使用 Rails5.1 开发环境是没有这个问题的 生产环境有 我不确定这是否是很明显的问题 我确定是 Origin 这个 header 但是一直在用 add_header, 正确的是 proxy_set_header.

Nginx: HTTP Origin header didn't match request.base_url

生产服务器报错

HTTP Origin header (https://www.baseico.com) didn't match request.base_url (http://baseico.com)
HTTP Origin header (https://baseico.com) didn't match request.base_url (http://baseico.com)
HTTP Origin header didn't match request.base_url 

Nginx 的配置信息如下

location / {
     #proxy_set_header Access-Control-Allow-Origin *;
     #proxy_set_header Access-Control-Request-Method *;
     #add_header Origin http://$Host;
     #add_header Scheme http;
     proxy_set_header Origin http://$Host;

     proxy_pass http://baseico.com;
     proxy_set_header Host $Host;
     #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

正确配置为

location / {     
     proxy_set_header Origin http://$Host; #正确处理
     proxy_pass http://baseico.com;
     proxy_set_header Host $Host;
}

报错的地方我在 rails 找到了 在这里https://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/request_forgery_protection.rb 211 行

def verify_authenticity_token # :doc:
  mark_for_same_origin_verification!

  if !verified_request?
    if logger && log_warning_on_csrf_failure
      if valid_request_origin?
        logger.warn "Can't verify CSRF token authenticity."
      else
        logger.warn "HTTP Origin header (#{request.origin}) didn't match request.base_url (#{request.base_url})"
      end
    end
    handle_unverified_request
  end
end

Nginx 配置了 HTTPS,所有的请求都是 https。但是到了 rails 端呢便是 http 了。nginx 的配置里面我尝试了修改某些参数 最终找到了 $Host 表示请求的 host,不包含 scheme 部分,scheme 部分为 http 或者 https 等等

proxy_set_header Origin http://$Host;

居然没人回答。。 我也碰到这个问题来着,最后用这里的方法解决了:https://github.com/rails/rails/issues/22965 @afair 的回答

我碰到的问题是处理 CORS 跨域问题在 nginx 改了不少配置,然后也全部换成了 https。 然后 devise 成功登录之后,访问本应该可以访问的页面给我 401 然后又跳到登录页面。 看到

HTTP Origin header (https://yuzhu.me) didn't match request.base_url (http://yuzhu.me)

查到上面的答案之后加了这些

问题解决。

我遇到了类似的问题,只是我的问题是我改了 nginx 的监听端口为 81,所以跟 base_url 不匹配了。还在探索中,有方案后在次更新

我的问题已经解决了,解决方案很简单,那就是将
proxy_set_header X-Forwarded-Host $host; 改为 proxy_set_header X-Forwarded-Host $host:81;

注意报错的时候说的是,“HTTP Origin header" 和 "request.base_url" 不匹配,其中“HTTP Origin header"是你 call 这个请求时候的除了去掉 path 部分的东西,就类似“http://localhost:3000/users"

那么 Origin:http://localhost:3000

而 request.base_url 这个值是根据 nignx 的配置算出来,所以如果你不配置 port 的话,他就没有 port。这个就是我遇到的错误的原因。所以我加上了 port 就好了。

今天遇到这个问题了,解决办法参考了这个 github issue

原因:nginx 配置文件里 proxy_set_header X-Forwarded-Proto http; (写死了 http);nginx 里处理 ssl 加解密,rails app 里的 redirect_to 请求被重定向到了 http 协议上

解决办法:改为 proxy_set_header X-Forwarded-Proto $scheme; 然后 reload 一下 nginx 配置文件

需要 登录 后方可回复, 如果你还没有账号请 注册新账号