你好,这是我在这里的第一篇文章!
几天来,我一直在尝试调试这个问题,但无法解决。当我向rails api发出post请求时,我收到了以前从未见过的错误:
Started POST "/owners" for ::1 at 2021-01-12 11:24:15 -0500
(1.0ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Processing by OwnersController#create as */*
Parameters: {"email"=>"adam", "password"=>"[FILTERED]", "owner"=>{"email"=>"adam"}}
HTTP Origin header (http://localhost:3000) didn't match request.base_url (http://localhost:3001)
Completed 422 Unprocessable Entity in 0ms (ActiveRecord: 1.8ms | Allocations: 476)
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
就像我说的,我以前从未见过这种情况,我不知道我是怎么造成的。我没有使用代理服务器,我在这个项目中尝试的唯一可能会把事情搞砸的新东西是我安装了设计宝石,但决定不使用它并删除了它。
我尝试过的东西:
确保我没有挂起的迁移:
检查我的路线:
Rails.application.routes.draw do
resources :owners
resources :dogs
post 'login', to: 'sessions#create'
end
然后我想这可能是一个cors问题:
require_relative 'boot'
require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
module Backend
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 6.0
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.
config.api_only = true
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource(
'*',
headers: :any,
methods: [:get, :patch, :put, :delete, :post, :options, :head]
)
end
end
end
end
然后,我尝试在谷歌上搜索关于无效真实性令牌和http原始标头的内容,但找不到有用的解决方案或我能理解的解决方案。
(最后一点:我试着把它从post请求改为get请求,它成功了,但posts导致了一个错误(
感谢您提前提供任何建议
在我的案例中,问题出在虚拟主机的Ngixn设置上。在以下位置找到答案:https://github.com/rails/rails/issues/22965#issuecomment-169956605
通过在Nginx(X-Forwarded-Ssl-on,X-Forwarded Port 443和X-Forwardd-Host主机名(中添加更多标头来修复
这是编辑后的部分:
location @app {
proxy_pass http://app;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header Host $http_host;
proxy_redirect off;
}
我认为这是一个CSRF(跨站点请求伪造(问题。Rails正在努力防止对您的控制器发出无效请求。它正在您的请求头上寻找authenticity_token
,该令牌通过html.erb
表单中的隐藏元素进入请求,用于将请求发布到特定路径。当您使用rails作为API时,这些令牌是不存在的。
有多种策略可以防止此异常,并且都具有不同的安全含义。这是一个很好的起点:Rails API设计,无需禁用CSRF保护
一种解决方案是将HTTP_X_FORWARDED_HOST
标头设置为与HTTPOrigin
标头相同的值。Origin
标头由浏览器设置,在您的情况下,它将被设置为http://localhost:3000
。设置主机标头将导致HTTPOrigin
与request.base_url
匹配。这是因为base_url
是由Rack使用这些标头创建的(源代码–您可以在此处看到所有标头(。
另一个选项是将Rails.application.config.forgery_protection_origin_check
(文档(设置为false
。不过,这应该只适用于开发环境,因为您仍然需要在生产中提供这种保护。