delphi - 访问 Ubuntu One API 结果为 "401 UNAUTHORIZED"或 "400 BAD REQUEST"

标签 delphi oauth indy10

我正在使用 Delphi XE2 和 Indy 10 来访问 Ubuntu One API。到目前为止,一切都很好。我能够从云中获取 OAuth token described 。现在我想开始使用 API(如 described ):

function TUbuntuOneApi.DoRequest(const URL: String): String;
var
  RequestParams: TStringList;
  HeaderIndex: Integer;
const
  OAuthAuthorisationHeader = 'OAuth realm="", oauth_version="%s", oauth_nonce="%s", oauth_timestamp="%s", oauth_consumer_key="%s", oauth_token="%s", oauth_signature_method="%s", oauth_signature="%s"';

begin
  RequestParams := SignOAuthRequestParams(URL, fOAuthAppToken, fOAuthAccessToken);

{  OAuth realm="", oauth_version="1.0",
  oauth_nonce="$nonce", oauth_timestamp="$timestamp",
  oauth_consumer_key="$consumer_key", oauth_token="$token",
  oauth_signature_method="PLAINTEXT",
  oauth_signature="$consumer_secret%26$token_secret"
  }

  HeaderIndex := IdHTTP.Request.CustomHeaders.IndexOfName('Authorization');
  if HeaderIndex >= 0 then
  begin
    IdHTTP.Request.CustomHeaders.Delete(HeaderIndex);
  end;

  // Solving: http://stackoverflow.com/questions/7323036/twitter-could-not-authenticate-with-oauth-401-error
  IdHTTP.Request.CustomHeaders.FoldLines := false;

  IdHTTP.Request.CustomHeaders.AddValue('Authorization', Format(OAuthAuthorisationHeader, [
      TIdURI.URLDecode(RequestParams.Values['oauth_version']),
      TIdURI.URLDecode(RequestParams.Values['oauth_nonce']),
      TIdURI.URLDecode(RequestParams.Values['oauth_timestamp']),
      TIdURI.URLDecode(RequestParams.Values['oauth_consumer_key']),
      TIdURI.URLDecode(RequestParams.Values['oauth_token']),
      TIdURI.URLDecode(RequestParams.Values['oauth_signature_method']),
      TIdURI.URLDecode(RequestParams.Values['oauth_signature'])
    ]));

  // Execute
  Result := IdHTTP.Get(URL);
  RequestParams.Free;
end;

function TUbuntuOneApi.Test: String;
begin
  //Result := DoRequest('https://one.ubuntu.com/api/file_storage/v1');
  Result := DoRequest('https://one.ubuntu.com/api/account/');
end;

调用https://one.ubuntu.com/api/file_storage/v1结果是“401 未经授权”。调用https://one.ubuntu.com/api/account/结果是“400 错误请求”。 OAuth 库来自SourceForge并与 Dropbox 配合使用(如果 OAuth 参数位于查询字符串中,则 Dropbox 接受它们)。 token 正确且有效。我做错了什么?

顺便说一句:

function SignOAuthRequestParams(const URL: String; OAuthAppToken, OAuthAccessToken: TOAuthToken): TStringList;
var
  Consumer: TOAuthConsumer;
  ARequest: TOAuthRequest;
  Response: String;
  HMAC: TOAuthSignatureMethod;
begin
  HMAC := TOAuthSignatureMethod_PLAINTEXT.Create;
  // Consumer erzeugen
  Consumer := TOAuthConsumer.Create(OAuthAppToken.Key, OAuthAppToken.Secret);

  // Request erzeugen
  ARequest := TOAuthRequest.Create(URL);
  ARequest := ARequest.FromConsumerAndToken(Consumer, OAuthAccessToken, URL);
  ARequest.Sign_Request(HMAC, Consumer, OAuthAccessToken);

  Result := TStringList.Create;
  Result.AddStrings(ARequest.Parameters);

  ARequest.Free;
  Consumer.Free;
  HMAC.Free;
end;

最佳答案

At this point, the newly created token can be used to authenticate to other methods, on the Ubuntu SSO service, but can not yet be used with the Ubuntu One API. We need to tell Ubuntu One to copy the newly created token from the SSO service. This is done by issuing a GET request to the following URL, signed with the new OAuth token. From Ubuntu One: Authorization page.

真丢脸,我忘了这么做。

关于delphi - 访问 Ubuntu One API 结果为 "401 UNAUTHORIZED"或 "400 BAD REQUEST",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13267642/

相关文章:

google-apps-script - 如何从 Google Apps 脚本授权 Google Speech-to-text?

Delphi indy 将流发送到客户端

c++ - 如何使用 indy 10.5.5 c++ 写入和读取 Stream

delphi - 如何确保在调用 FreeLibrary 之前释放 Interface 实例

delphi - 如何确定 Delphi 对象是否属于特定类而不是任何后代类?

delphi - writeln (“:width” 说明符的明显副作用会导致输出中出现问号)

php - Twitter API,从数据库到 Twitter

delphi - 在 Delphi 中使用 Windows 和 MMSystem

java - Java 中的两条腿 OAuth2 示例?

delphi - 回复 Indy 10 中的地址?