使用 curl 将 POST 认证为 Rails 的问题
Issue with an authenicated POST to Rails using curl
我正在寻找 POST 来自 curl 的 Rails 应用程序。我已经能够进行身份验证并获得 200 响应。但是当我尝试 POST 一些数据时它失败了。
我的控制器代码:
class TestApiController < ApplicationController
before_action :authenticate
def server_reporter
puts params
end
protected
def authenticate
authenticate_or_request_with_http_token do |token, options|
# User.find_by(auth_token: token)
token == '1234'
end
end
end
当我运行这个
curl -v localhost:3000/test_api/server_reporter -IH "Authorization: Token token=1234"
我明白了
Started HEAD "/test_api/server_reporter" for ::1 at 2016-10-10 11:27:19 +0200
Processing by TestApiController#server_reporter as */*
{"controller"=>"test_api", "action"=>"server_reporter"}
Rendered test_api/server_reporter.html.erb within layouts/application (0.2ms)
Completed 200 OK in 221ms (Views: 220.2ms | ActiveRecord: 0.0ms)```
当我尝试时
curl -v localhost:3000/test_api/server_reporter -X POST -H "Authorization: Token token=1234" -H "Content-Type: application/json" -d '{"server": {"name": "Asterix"}}'
我在 Rails 控制台中得到以下信息。
Started POST "/test_api/server_reporter" for ::1 at 2016-10-10 15:59:36 +0200
Processing by TestApiController#server_reporter as */*
Parameters: {"server"=>{"name"=>"Asterix"}, "test_api"=>{"server"=>{"name"=>"Asterix"}}}
Can't verify CSRF token authenticity
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)
ActionController::InvalidAuthenticityToken - ActionController::InvalidAuthenticityToken:
编辑:添加 curl
响应。
$ curl -v localhost:3000/test_api/server_reporter -X POST -H "Authorization: Token token=1234" -H "Content-Type: application/json" -d '{"server": {"name": "Asterix"}}'
* Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> POST /test_api/server_reporter HTTP/1.1
> Host: localhost:3000
> User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
> Accept: */*
> Referer:
> Authorization: Token token=1234
> Content-Type: application/json
> Content-Length: 31
>
* upload completely sent off: 31 out of 31 bytes
< HTTP/1.1 422 Unprocessable Entity
< Content-Type: text/plain; charset=utf-8
< X-Meta-Request-Version: 0.4.0
< X-Request-Id: a13faa8e-20b4-4107-ba5f-1c6fde1f8ce1
< X-Runtime: 0.077414
< Set-Cookie: __profilin=p%3Dt; path=/
< Connection: close
< Server: thin
<
ActionController::InvalidAuthenticityToken at /test_api/server_reporter
=======================================================================
> ActionController::InvalidAuthenticityToken
在 ApplicationController 的顶部添加以下行后尝试。
skip_before_action :verify_authenticity_token
更新
为了防止伪造,Rails 会在调用HTML 请求时自动在参数中设置身份验证令牌。为此,您需要在 application.html.erb 中添加 csrf_meta_tags
,如下所示。
<!DOCTYPE html>
<html>
<head>
<title>Sample</title>
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
如果它是一个基于 API 的应用程序,您可以添加下面的行以跳过它,因为只有 HTML 请求才需要它。
protect_from_forgery unless: -> { request.format.json? }
我正在寻找 POST 来自 curl 的 Rails 应用程序。我已经能够进行身份验证并获得 200 响应。但是当我尝试 POST 一些数据时它失败了。
我的控制器代码:
class TestApiController < ApplicationController
before_action :authenticate
def server_reporter
puts params
end
protected
def authenticate
authenticate_or_request_with_http_token do |token, options|
# User.find_by(auth_token: token)
token == '1234'
end
end
end
当我运行这个
curl -v localhost:3000/test_api/server_reporter -IH "Authorization: Token token=1234"
我明白了
Started HEAD "/test_api/server_reporter" for ::1 at 2016-10-10 11:27:19 +0200
Processing by TestApiController#server_reporter as */*
{"controller"=>"test_api", "action"=>"server_reporter"}
Rendered test_api/server_reporter.html.erb within layouts/application (0.2ms)
Completed 200 OK in 221ms (Views: 220.2ms | ActiveRecord: 0.0ms)```
当我尝试时
curl -v localhost:3000/test_api/server_reporter -X POST -H "Authorization: Token token=1234" -H "Content-Type: application/json" -d '{"server": {"name": "Asterix"}}'
我在 Rails 控制台中得到以下信息。
Started POST "/test_api/server_reporter" for ::1 at 2016-10-10 15:59:36 +0200
Processing by TestApiController#server_reporter as */*
Parameters: {"server"=>{"name"=>"Asterix"}, "test_api"=>{"server"=>{"name"=>"Asterix"}}}
Can't verify CSRF token authenticity
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)
ActionController::InvalidAuthenticityToken - ActionController::InvalidAuthenticityToken:
编辑:添加 curl
响应。
$ curl -v localhost:3000/test_api/server_reporter -X POST -H "Authorization: Token token=1234" -H "Content-Type: application/json" -d '{"server": {"name": "Asterix"}}'
* Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> POST /test_api/server_reporter HTTP/1.1
> Host: localhost:3000
> User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
> Accept: */*
> Referer:
> Authorization: Token token=1234
> Content-Type: application/json
> Content-Length: 31
>
* upload completely sent off: 31 out of 31 bytes
< HTTP/1.1 422 Unprocessable Entity
< Content-Type: text/plain; charset=utf-8
< X-Meta-Request-Version: 0.4.0
< X-Request-Id: a13faa8e-20b4-4107-ba5f-1c6fde1f8ce1
< X-Runtime: 0.077414
< Set-Cookie: __profilin=p%3Dt; path=/
< Connection: close
< Server: thin
<
ActionController::InvalidAuthenticityToken at /test_api/server_reporter
=======================================================================
> ActionController::InvalidAuthenticityToken
在 ApplicationController 的顶部添加以下行后尝试。
skip_before_action :verify_authenticity_token
更新
为了防止伪造,Rails 会在调用HTML 请求时自动在参数中设置身份验证令牌。为此,您需要在 application.html.erb 中添加 csrf_meta_tags
,如下所示。
<!DOCTYPE html>
<html>
<head>
<title>Sample</title>
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
如果它是一个基于 API 的应用程序,您可以添加下面的行以跳过它,因为只有 HTML 请求才需要它。
protect_from_forgery unless: -> { request.format.json? }