Ruby on rails 如何使用curl发布而不获取HTTP错误422';无法处理的实体';?

Ruby on rails 如何使用curl发布而不获取HTTP错误422';无法处理的实体';?,ruby-on-rails,forms,http,curl,Ruby On Rails,Forms,Http,Curl,我正在尝试向登录端点发送POST请求。我不断收到HTTP错误422“无法处理的实体”。我如何克服这个错误 以下是我尝试过的一些命令示例: curl -v -X POST -F 'user[email]=test@email.com' -F 'user[password]=password' https://example.com/users/sign_in curl -v -H 'Accept: text/html,application/xhtml+xml,application/xml;'

我正在尝试向登录端点发送POST请求。我不断收到HTTP错误
422“无法处理的实体”
。我如何克服这个错误

以下是我尝试过的一些命令示例:

curl -v -X POST -F 'user[email]=test@email.com' -F 'user[password]=password' https://example.com/users/sign_in

curl -v -H 'Accept: text/html,application/xhtml+xml,application/xml;' -H 'Content-Type: application/x-www-form-urlencoded' -d 'utf8=%E2%9C%93&authenticity_token=123456789123456789123456789123123123456456456789789789789VX4KgMBr6zgGjo123456789123456789njQ%3D%3D&user%5Bemail%5D=test%40sign_in.com&user%5Bpassword%5D=password&commit=Sign+in' https://example.com/users/sign_in
我希望请求发回
200
301
/
302
响应状态,但我得到的是:

* upload completely sent off: 208 out of 208 bytes
< HTTP/1.1 422 Unprocessable Entity
< Server: nginx/1.12.2
< Date: Fri, 08 Feb 2019 12:08:07 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 0
< Connection: keep-alive
< X-Request-Id: 6ceb5baa-7740-448a-8105-6f67dd203fbb
< X-Runtime: 0.021676

有没有办法克服这个问题?我所要做的就是确保需要验证的路由返回200/301/302响应。

至少有两种方法可以做到这一点:

选项1:获取并使用令牌 解决这个问题的一种方法是实际捕获并利用rails生成的真实性令牌。要做到这一点,我们还需要捕获并发送回cookie,以允许我们利用与生成的令牌关联的会话。我可以用下面的咒语来做这个

(注意:我假设已经为“thing”创建了一个脚手架,创建了一个
things\u controller.rb
,等等。根据需要调整它以适应您的用例。)

步骤1:捕获令牌: 步骤2:在请求中使用它: 这是可行的,对应用程序没有任何更改。当我运行它时,我看到一个成功的对象创建将JSON呈现为输出

(如果只需要原始JSON数据,可以忽略
|jq.
,或者将其发送到其他地方。)

然而,还有另一种选择。对控制器稍加调整,就可以实现更简单的
curl
使用(不需要cookiejar,参数更少,只有一个curl命令,并且没有奇怪的嵌套引号),如下所示:


选项2:禁用令牌检查: 另一种方法是禁用
validity\u令牌
检查您希望允许此类操作的任何控制器中的
create
操作。例如,在我的一个名为“thing”的脚手架示例中,可以更新
app/controllers/things\u controller.rb
文件以添加第二行,如下所示:

class ThingsController < ApplicationController                     # EXISTING LINE
  skip_before_action :verify_authenticity_token, only: [:create]   # NEW LINE
  before_action :set_img, only: [:show, :edit, :update, :destroy]  # EXISTING LINE
  # ... additional content elided ...

再次,我看到了
jq
生成的输出,这次不需要捕获cookie或令牌或任何东西。

至少有两种方法可以做到这一点:

选项1:获取并使用令牌 解决这个问题的一种方法是实际捕获并利用rails生成的真实性令牌。要做到这一点,我们还需要捕获并发送回cookie,以允许我们利用与生成的令牌关联的会话。我可以用下面的咒语来做这个

(注意:我假设已经为“thing”创建了一个脚手架,创建了一个
things\u controller.rb
,等等。根据需要调整它以适应您的用例。)

步骤1:捕获令牌: 步骤2:在请求中使用它: 这是可行的,对应用程序没有任何更改。当我运行它时,我看到一个成功的对象创建将JSON呈现为输出

(如果只需要原始JSON数据,可以忽略
|jq.
,或者将其发送到其他地方。)

然而,还有另一种选择。对控制器稍加调整,就可以实现更简单的
curl
使用(不需要cookiejar,参数更少,只有一个curl命令,并且没有奇怪的嵌套引号),如下所示:


选项2:禁用令牌检查: 另一种方法是禁用
validity\u令牌
检查您希望允许此类操作的任何控制器中的
create
操作。例如,在我的一个名为“thing”的脚手架示例中,可以更新
app/controllers/things\u controller.rb
文件以添加第二行,如下所示:

class ThingsController < ApplicationController                     # EXISTING LINE
  skip_before_action :verify_authenticity_token, only: [:create]   # NEW LINE
  before_action :set_img, only: [:show, :edit, :update, :destroy]  # EXISTING LINE
  # ... additional content elided ...

再次,我看到了
jq
生成的输出,这一次不需要捕获cookie或令牌或任何东西。

当你请求时,你能显示rails的日志吗?@arieljuod感谢你的回复-我用rails日志的摘录更新了帖子。关于如何使用有效的真实性令牌发布到curl,您有什么想法吗?该令牌目前由rails生成(您需要执行两个请求,一个请求到实际登录页面,解析它并获取令牌来执行curl请求)。如果你知道你在做什么,你也可以禁用令牌验证,检查这个,并在这里阅读关于令牌的信息。当你请求时,你能显示rails的日志吗?@arieljuod谢谢你的回复-我用rails日志的摘录更新了这篇文章。关于如何使用有效的真实性令牌发布到curl,您有什么想法吗?该令牌目前由rails生成(您需要执行两个请求,一个请求到实际登录页面,解析它并获取令牌来执行curl请求)。如果您知道自己在做什么,您也可以禁用令牌验证,请选中此项并阅读此处关于令牌的旁注:感谢@epigene和关于如何执行选项2的类似问题。旁注:感谢@epigene和关于如何执行选项2的类似问题。
cat myjar | \
  curl -b - -s \
        -H "Accept: application/json" \
        -H "Content-type: application/json" \
        -d '{"thing": {"field1":"Test","field2":"Testing"},
             "authenticity_token":"'"$token"'"}' \
        https://example.com/things | jq .
class ThingsController < ApplicationController                     # EXISTING LINE
  skip_before_action :verify_authenticity_token, only: [:create]   # NEW LINE
  before_action :set_img, only: [:show, :edit, :update, :destroy]  # EXISTING LINE
  # ... additional content elided ...
curl -s \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -d '{"thing": {"field1":"Test","field2":"Testing"}}' \
  http://example.com/things | jq .