2012-11-07 185 views
5

我使用Delphi XE2与Indy 10访问Ubuntu One API。到现在为止还挺好。我能够从云端获得OAuth令牌described。现在我要开始使用API​​(如described):访问Ubuntu One API导致“401 UNAUTHORIZED”或“400 BAD REQUEST”

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 BAD REQUEST”。 OAuth Library从SourceForge开始使用Dropbox(Dropbox接受OAuth-Params,如果它们在查询字符串中)。令牌是正确和有效的。我究竟做错了什么?

BTW:

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; 

回答

1

在这一点上,新创建的标记可以用于身份验证到其他 方法,在Ubuntu SSO服务,但还不能与 Ubuntu的一个使用API。我们需要告诉Ubuntu One从SSO服务中复制新创建的令牌 。这通过向以下URL发出GET 请求完成,并使用新的OAuth令牌进行签名。 从Ubuntu One: Authorization page

对我感到羞耻,我忘了这么做。