【问题标题】:How to POST to Rails with cURL?如何使用 cURL 发布到 Rails?
【发布时间】:2021-04-29 10:17:07
【问题描述】:

我需要将外部目录引用(json 文件)上传到我的用户数据。这是学习如何创建 API 和使用 cURL 的好机会,但我仍然遇到了至少一个问题。

我从单个元素开始,但我计划在故事结尾传递一个 json 数据文件。要加载的典型元素如下所示:

{“名称”:“测试”,“id”:“35”,“external_id”:“X-001”}

我浏览了 cURL 手册和几篇 StackOverflow 帖子,最终构建了这个 API:

在 routes.rb 中创建了专用路由

match '/API/user_directory', to: "users#set_external_reference", via: :post

向用户控制器添加了一个方法

def set_external_reference
  puts "Loaded parameters:"
  puts params
  if target_user = User.find(params[:id])
    target_user.update_attributes(external_directory_id: params[:external_id])
    render json: {"Response": "OK"}, status: 200
  else
    render json: {"Response": "not OK"}, status: 500
  end
end

解决方法在用户控制器中设计身份验证要求和 CanCanCan 授权

class UsersController < ApplicationController
# Check for active session 
  before_action :authenticate_user! unless ->{:action == 'set_external_reference'}
  load_and_authorize_resource except: :set_external_reference

在应用程序控制器中解决 CSRF

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception unless -> { request.format.json? }

如果这是一个好的方法,或者如果它使网站暴露于安全威胁,我很高兴收到您的来信。

但是当我尝试运行 cURL 请求时问题出现了:

curl --noproxy localhost -d "{"name": "Test", "id": "35", "external_id": "X-001"}" -H "Accept: application/json" -H "Content-type: application/json" http://localhost/API/user_directory > error.html

尝试解析请求参数时出现以下错误:

UsersController#set_external_reference 中的 ActionDispatch::Http::Parameters::ParseError

767:“{name: Test, id: 35, external_id: X-001}”处出现意外令牌

在这一点上,我找不到这个问题的线索。你能提供一些帮助吗? 非常感谢!

【问题讨论】:

  • 我认为有效载荷不是有效的 JSON。尝试类似“{\”name\":\"Test\",\"id\":\"35\",\"external_id\":\"X-001\"}"。或者验证您的 JSON 负载以检查它是否有效。
  • {"name": "Test", "id": "35", "external_id": "X-001"} 和 "{\"name\":\"Test\" ,\"id\":\"35\",\"external_id\":\"X-001\"}" 被验证器接受。但 "{"name": "Test", "id": "35", "external_id": "X-001"}" 不是。由于第一个是我输入文件的格式,所以我将参数传递到一个文件中,例如:-d @external_ids.json
  • 我最初尝试过 -d '{"name": "Test", "id": "35", "external_id": "X-001"}',但这会引发 URL 错误.
  • set_external_reference方法中puts params这一行的输出是什么
  • {"controller"=>"users", "action"=>"set_external_reference", "user"=>{}}

标签: ruby-on-rails json curl


【解决方案1】:

我建议您通过将 JSON 输入放入文件中来避免 shell 所需的 JSON 语法问题和转义。如果文件名为params.json,则使用-d @params.json 从文件中传递它。

至于身份验证,我也不确定这是否是个好主意,但您可能会找到一个会话密钥并将其传递到 cookie 标头中。如果您正在使用数据库会话(这是一个好主意),那么它将是数据库中会话列中的值。如果没有,请使用开发工具并从浏览器获取会话。

【讨论】:

  • 与@Farhad Ajaz 聊天让我们得出了同样的结论。谢谢你们。
  • 身份验证基于 Devise gem,我认为会话令牌不容易访问......但是使用开发工具,不是吗?
  • 这些 cmets 似乎几乎解决了问题,但缺少数据文件的建议,这是一种更简洁的方式来处理必要的 shell 转义,应该为后代写一篇文章。我的 RoR 银质徽章还需要 10 分。
  • 会话密钥作为 cookie 传递给 Web 服务器。使用浏览器的开发工具可以看到 cookie。数据库会话将使其更可用。 (会话也在设计仅使用的机架层中进行管理。)
猜你喜欢
  • 2010-10-23
  • 1970-01-01
  • 1970-01-01
  • 2012-03-03
  • 2010-11-03
  • 2012-02-23
  • 2023-03-26
  • 1970-01-01
相关资源
最近更新 更多