在网络方面,我有两个字段:名称和文档。 Document是一个文件字段,name就是用户想要在应用程序中调用该文件的名称。
以下是我的尝试:
curl -F "media[document]=@a.png" -F "media[name]=api" "http://example.com/medias/create.xml?api_key=123"
但是我收到了InvalidAuthenticityToken错误。 仅当我尝试上载文件/制作媒体对象时才会出现此错误。其他API / xml命令可以工作(不涉及文件的那些)
使用cURL上传文件的正确方法是什么?
编辑: 在上面的curl命令中添加-H“Content-Type:application / xml”会使服务器生成此错误:
/!\ FAILSAFE /!\ Tue Jan 24 08:45:03 -0500 2012
Status: 500 Internal Server Error
#<REXML::ParseException: malformed XML: missing tag start
Line:
Position:
Last 80 unconsumed characters:
<:??OH?ɽ?H? ???g??yx~t????op?.$?????P&W ??"?
通常使用-d参数提供XML。但我不认为文件可以包含在xml中?也许他们可以? IDK的。
答案 0 :(得分:9)
如果要从xml创建文件,则应根据需要将xml格式化为data和/或Base64使用CDATA。一旦你有一个格式正确的xml文件,你只需要用curl发送它。
如果您只想上传文件,则无需使用xml界面。你可以打电话:
curl -F "media[document]=@./a.png;type=image/png" -F "media[name]=api" "http://example.com/medias/
对于你的身份验证问题,如果你仍然在这个网址上(我没有在新的rails 3.2.1新应用程序上遇到它),你可以使用常规浏览器访问它,获取cookie信息并发送卷曲。这意味着您将添加到您的命令:
--cookie "csrf-param=authenticity_token" --cookie "csrf-value=XXXXXXX"
或使用convenient script将所有当前的Firefox Cookie从主机发送到curl。
答案 1 :(得分:3)
Rails使用authenticity token来阻止CSRF。它将基于当前用户会话计算的特殊令牌插入到每个表单中,并在请求到达服务器时进行检查。
当您使用curl执行POST请求时,您会收到该错误,因为您没有将有效的真实性令牌传递给服务器。您可以为此方法禁用该保护(注意,禁用它会使此操作对CSRF易受攻击):
protect_from_forgery :except => :some_action
或者您可以使用某些ninja magic将有效的真实性令牌传递给服务器。
另一个选择是基于Rails仅针对具有特定内容类型的请求检查真实性令牌的事实。如果它是一个API并且您在JSON中获得响应,您可以尝试将请求的内容类型设置为application/json
,如下所示:
curl -H "Content-Type: application/json" ...
答案 2 :(得分:2)
您需要为操作禁用真实性令牌。在控制器中使用它(我假设操作名为create
):
protect_from_forgery :except => [:create]
这只发生在POST,PUT或DELETE请求中,这可能是其他请求成功的原因。
如果这是一个API,您将需要完全禁用它。您可以删除protect_from_forgery
中的ApplicationController
。
真实性令牌用于(在某种程度上)确保用户在修改资源时浏览表单。应用程序创建与用户会话关联的随机令牌,并将其放在表单的隐藏字段中。提交表单时,将令牌与存储在会话中的令牌进行比较以进行检查。这在API中没有任何意义。