如何在Delphi中使用DropBox REST API复制文件

22

使用Dropbox API进行文件复制操作时,我好像无法成功实现。我可以成功授权我的客户端、下载和上传文件。复制操作需要使用POST方法,我认为这就是我出错的地方。我正在定义OAuth身份验证的POST方法,并使用Indy TIdHTTP来提交请求,但我始终收到错误代码403 - 权限被拒绝。

以下是Dropbox API的说明:https://www.dropbox.com/developers/reference/api#fileops-copy

以下是我的部分代码:

 ParamStr := Format('root=%s&from_path=%s&to_path=%s', [Root, EncodeFileName(FromPath), EncodeFileName(ToPath)]);
 URL := 'https://api.dropbox.com/1/fileops/copy' + '?' + ParamStr;

 Consumer := TOAuthConsumer.Create(Key, Secret);
 AToken := TOAuthToken.Create(fToken, fTokenSecret);
 HMAC := TOAuthSignatureMethod_HMAC_SHA1.Create;
 ARequest := TOAuthRequest.Create('');
 try
  ARequest.HTTPURL := URL;
  ARequest.Method := 'POST';
  ARequest := ARequest.FromConsumerAndToken(Consumer, AToken, '');
  ARequest.Sign_Request(HMAC, Consumer, AToken);


  Params := TStringList.Create;
  try
   Params.Text := ParamStr + '&' + ARequest.GetString;
   HTTP.Post(URL, Params);
  finally
   Params.Free;
  end;

1
@Tlama,缺少SSL库是否也会干扰授权、上传和下载操作,这些操作应该是正常工作的? - Rob Kennedy
1
我肯定有SSL库。正如我所说,它可以与所有GET和PUT方法的API一起使用。 - Nostradamus
2
没有同名的文件或文件夹,我已经多次检查了路径确保正确。我只是尝试复制单个文件。目标文件夹存在,源文件也存在。 - Nostradamus
只是为了明确,这些路径是相对于Dropbox根目录的吗? - Jason
最后我建议逐个将参数添加到字符串列表中。据我所知,这将在参数中结束一个条目。尝试使用Params.Add(root =%s);等。 - Jason
显示剩余4条评论
2个回答

1
我想我可能发现了问题所在。我不了解 TOAuthRequest 类,但我猜测 GetString 方法会给出标准的 OAuth 头部 'Authorization Bearer {KEY}'。正确的方法是将它添加到 HTTP 请求中。
HTTP.Request.CustomHeaders.AddValue('Authorization', <the rest of the string here>)

相反,您将该字符串添加到正文中,这可能对Get请求有效,因为正文(授权字符串)被误认为是头文件,但是对于POST方法,您实际上在授权字符串之前有一个实际的正文,因此OAuth字符串被忽略。

最后,我不认为您还需要在正文中使用参数字符串。一个空正文应该可以正常工作。查询字符串似乎可以接受。

示例代码:

  ParamStr := Format('root=%s&from_path=%s&to_path=%s', [Root, EncodeFileName(FromPath), EncodeFileName(ToPath)]);
 URL := 'https://api.dropbox.com/1/fileops/copy' + '?' + ParamStr;

 Consumer := TOAuthConsumer.Create(Key, Secret);
 AToken := TOAuthToken.Create(fToken, fTokenSecret);
 HMAC := TOAuthSignatureMethod_HMAC_SHA1.Create;
 ARequest := TOAuthRequest.Create('');
 try
  ARequest.HTTPURL := URL;
  ARequest.Method := 'POST';
  ARequest := ARequest.FromConsumerAndToken(Consumer, AToken, '');
  ARequest.Sign_Request(HMAC, Consumer, AToken);



  HTTP.Request.CustomHeaders.AddValue('Authorization', <parsed ARequest.GetString>)
  HTTP.Post(URL);

希望这能有所帮助。

1
据我所知,当与Indy一起使用时,参数会被复制到消息的正文中而不是URL中,请尝试使用以下内容:
http:Post(URL+encodeparams(params));

我不确定这是否是正确的语法,但这就是想法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接