如何使用curl进行发布而不获取HTTP错误422“无法处理的实体"? [英] How to POST with curl and not get HTTP error 422 'Unprocessable Entity'?

查看:185
本文介绍了如何使用curl进行发布而不获取HTTP错误422“无法处理的实体"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试向登录端点发送POST请求.我不断收到HTTP错误 422'Unprocessable Entity'.如何克服这个错误?

I am trying to send a POST request to an sign in endpoint. I keep getting HTTP error 422 'Unprocessable Entity'. How do I get past this error?

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

Here are some examples of commands I have tried:

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 响应状态,但是我得到了:

I want the request to send back a 200 or 301/302 response status, but instead I get this:

* 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

任何帮助或建议,我们都会感激不尽.谢谢

Any help or advice is appreciated. Thanks

更新

我现在看到来自这样一个请求的Rails日志呈现了一个InvalidAuthenticityToken错误

I see now that the Rails log from such a request renders an InvalidAuthenticityToken Error

Started POST "/users/sign_in" for 127.0.0.1 at 2019-02-08 14:30:50 +0000
Processing by Users::SessionsController#create as */*
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)

ActionController::InvalidAuthenticityToken - ActionController::InvalidAuthenticityToken:

关于如何克服这一点的任何想法?我要做的就是确保需要身份验证的路由返回200/301/302响应.

Any ideas on how to get past this? All I am seeking to do is ensure that routes which require authentication are returning 200/301/302 responses.

推荐答案

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

There are at least two ways to do this:

解决此问题的一种方法是实际捕获并利用rails生成的真实性令牌.为此,我们还需要捕获然后发送回cookie,以允许我们自己利用与所生成令牌相关联的会话.我能够使它与下面的咒语一起工作.

One way to solve this is to actually capture and utilize the authenticity token that rails generates. To do this, we also need to capture and then send back cookies, to allow ourselves to utilize a session that is associated with the generated token. I was able to get this to work with something like the following incantation.

(注意:我假设已经为事物"创建了一个脚手架,创建了一个 things_controller.rb 等,并根据需要将其调整为您的用例.)

(Note: I'm assuming a scaffold has been created for "thing", creating a things_controller.rb, etc. Adapt this to your use case as needed.)

token=$(curl -s -c myjar https://example.com/things/new | \
     sed -n 's/.*name="authenticity_token" value="\([^"]*\)".*/\1/p')

步骤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 .

此方法有效,无需对应用程序进行任何更改.运行该命令时,我会看到成功创建对象后将JSON呈现为漂亮的输出.

This works, without any changes to the application. When I run that, I see a pretty rendering of the JSON from a successful object creation as output.

(如果您只想要原始JSON数据,也许将其发送到其他内容,则忽略 | jq..)

但是,还有另一种选择.通过对控制器进行小的调整,可以实现更简单的 curl 使用(不需要cookiejar,更少的参数,仅一个curl命令,并且没有奇怪的嵌套引号),如下所示:

However, there is another option. With a small tweak to the controller, one can achieve a bit easier curl usage (no cookiejar required, fewer parameters, only a single curl command, and no strange nested quotes), as follows:

克服此问题的另一种方法是禁用 validity_token ,以检查要允许此类操作的任何控制器中的 create 操作.例如,以我的名为"thing"的脚手架为例,可以更新 app/controllers/things_controller.rb 文件以添加此处显示的第二行:

Another way to get past this is to disable the validity_token checking for the create action in any controller(s) you wish to allow this sort of thing from. For example, given my example of a scaffold called "thing", one might update the app/controllers/things_controller.rb file to add the second line shown here:

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 ...

然后,rails根本不会执行该检查,因此可以执行一步式重新设置,例如:

And then rails simply won't do that check, so one can do a one-step requset something like:

curl -s \
  -H "Accept: application/json" \
  -H "Content-type: application/json" \
  -d '{"thing": {"field1":"Test","field2":"Testing"}}' \
  http://example.com/things | jq .

同样,我这次看到的是 jq 生成的输出,而不必捕获cookie或令牌或任何东西.

Again, I see the jq-generated output, this time without having to capture cookies or a token or anything.

这篇关于如何使用curl进行发布而不获取HTTP错误422“无法处理的实体"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆