ruby-on-rails - 如何使用 curl 发布而不收到 HTTP 错误 422 'Unprocessable Entity'?
问题描述
我正在尝试向登录端点发送 POST 请求。我不断收到 HTTP 错误422 'Unprocessable Entity'
。我如何克服这个错误?
以下是我尝试过的一些命令示例:
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
任何帮助或建议表示赞赏。谢谢
更新
我现在看到来自此类请求的 Rails 日志呈现 InvalidAuthenticityToken 错误
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 响应。
解决方案
至少有两种方法可以做到这一点:
选项 1:获取并使用令牌
解决此问题的一种方法是实际捕获和利用 rails 生成的真实性令牌。为此,我们还需要捕获并发送回 cookie,以允许我们利用与生成的令牌相关联的会话。我能够让它与下面的咒语一起工作。
(注意:我假设已经为“事物”创建了一个脚手架,创建了一个things_controller.rb
等。根据需要将其适应您的用例。)
步骤 1:捕获令牌:
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 的漂亮呈现。
(如果您只想要原始 JSON 数据,则忽略| jq .
它,也许将其发送到其他东西。)
但是,还有另一种选择。对控制器稍加调整,可以实现更简单的curl
使用(不需要 cookiejar,参数更少,只有一个 curl 命令,并且没有奇怪的嵌套引号),如下所示:
选项 2:禁用令牌检查:
解决此问题的另一种方法是禁用对您希望允许此类事情的任何控制器validity_token
中的操作的检查。create
例如,给定一个名为“thing”的脚手架示例,可能会更新app/controllers/things_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 ...
然后 rails 根本不会进行该检查,因此可以执行一步请求,例如:
curl -s \
-H "Accept: application/json" \
-H "Content-type: application/json" \
-d '{"thing": {"field1":"Test","field2":"Testing"}}' \
http://example.com/things | jq .
再次,我看到jq
- 生成的输出,这一次无需捕获 cookie 或令牌或任何东西。
推荐阅读
- async-await - 如何使用来自不同图形 api 调用的响应创建和返回对象
- python - 防止“除以零错误”的方法
- javascript - 如何从Javascript中的对象获取所有键名
- c# - Swashbuckle 可以为包含对象集合的表单生成正确的 OpenAPI 定义吗?
- java - 请解释这个 JAVA 程序的意外输出
- quantlib - Quantlib FixedRateBond 现金流
- maven - 无法从 Maven 和 NPM 的中央存储库中提取一些包
- reactjs - 在 React Context / Provider 中刷新 REST API
- python - 如何创建 PyTorch 可变张量?
- gdb - GDB:有什么方法可以构造“本地”方便的变量吗?