我正在使用 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/