在Trello API OAuth中访问令牌时获取无效签名

时间:2017-08-04 11:26:44

标签: php authentication oauth trello

我正在尝试在PHP中实现trello api的包装器。我得到了#34;无效的签名"在OAuth流程的最后一步,我必须从trello api访问令牌。 只是通过这条消息我就无法调试我做错了什么。

基本上我做的是......

  1. 发送获取请求令牌(https://trello.com/1/OAuthGetRequestToken)的请求。这很顺利。我回复了两个参数oauth_tokenoauth_token_secret
  2. 然后我打开了trello授权页面网址(https://trello.com/1/OAuthAuthorizeToken),其中包含步骤1中的参数oauth_token,应用名称和localhost处的返回网址。这也很顺利。 Trello重定向到localhost / callback,参数为oauth_tokenoauth_verifier
  3. 在回调中,我终于发送了获取访问令牌(https://trello.com/1/OAuthGetAccessToken)的请求。我添加了oauth_token&来自第1步的oauth_token_secret,来自第2步的oauth_verifier以及使用HMAC-SHA1方法的签名。当我收到消息"无效签名" !!!
  4. 的500内部错误时,这就出错了

    有人知道可能出现的问题吗?

    这是我在回调中使用的代码。

    $nonce = md5(mt_rand());
    $timestamp = time();
    
    $oauth_signature_base = 'GET&'.
        rawurlencode('https://trello.com/1/OAuthGetAccessToken').'&'.
        rawurlencode(implode('&', [
            'oauth_consumer_key='.rawurlencode('CONSUMER_KEY_HERE'),
            'oauth_nonce='.rawurlencode($nonce),
            'oauth_signature_method='.rawurlencode('HMAC-SHA1'),
            'oauth_timestamp='.rawurlencode($timestamp),
            'oauth_token='.rawurlencode('OAUTH_TOKEN_HERE'),
            'oauth_token_secret='.rawurlencode('OAUTH_TOKEN_SECRET_HERE'),
            'oauth_verifier='.rawurlencode('OAUTH_VERIFIER_HERE'),
            'oauth_version='.rawurlencode('1.0')
            ]));
    
    $signature = base64_encode(hash_hmac('sha1', $oauth_signature_base, 'CONSUMER_SECRET_HERE&', true));
    
    $params = [
        'oauth_consumer_key='.rawurlencode('CONSUMER_KEY_HERE'),
        'oauth_nonce='.rawurlencode($nonce),
        'oauth_signature_method='.rawurlencode('HMAC-SHA1'),
        'oauth_timestamp='.rawurlencode($timestamp),
        'oauth_token='.rawurlencode('OAUTH_TOKEN_HERE'),
        'oauth_token_secret='.rawurlencode('OAUTH_TOKEN_SECRET_HERE'),
        'oauth_verifier='.rawurlencode('OAUTH_VERIFIER_HERE'),
        'oauth_version='.rawurlencode('1.0'),
        'oauth_signature='.rawurlencode($signature)
    ];
    file_get_contents(sprintf('%s?%s', 'https://trello.com/1/OAuthGetAccessToken', implode('&', $params)));
    

1 个答案:

答案 0 :(得分:1)

在生成基本字符串或发送实际请求时,不应在URL参数中包含oauth令牌密钥。令牌秘密仅用作散列密钥的一部分。请参阅以下修改后的代码:

$nonce = md5(mt_rand());
$timestamp = time();

$oauth_signature_base = 'GET&'.
rawurlencode('https://trello.com/1/OAuthGetAccessToken').'&'.
rawurlencode(implode('&', [
    'oauth_consumer_key='.rawurlencode('CONSUMER_KEY_HERE'),
    'oauth_nonce='.rawurlencode($nonce),
    'oauth_signature_method='.rawurlencode('HMAC-SHA1'),
    'oauth_timestamp='.rawurlencode($timestamp),
    'oauth_token='.rawurlencode('OAUTH_TOKEN_HERE'),
    'oauth_verifier='.rawurlencode('OAUTH_VERIFIER_HERE'),
    'oauth_version='.rawurlencode('1.0')
    ]));

//token secret should be (singly) URL encoded if not already
$signature = base64_encode(hash_hmac('sha1', $oauth_signature_base, 'CONSUMER_SECRET_HERE&TOKEN_SECRET_HERE', true));

$params = [
'oauth_consumer_key='.rawurlencode('CONSUMER_KEY_HERE'),
'oauth_nonce='.rawurlencode($nonce),
'oauth_signature_method='.rawurlencode('HMAC-SHA1'),
'oauth_timestamp='.rawurlencode($timestamp),
'oauth_token='.rawurlencode('OAUTH_TOKEN_HERE'),
'oauth_verifier='.rawurlencode('OAUTH_VERIFIER_HERE'),
'oauth_version='.rawurlencode('1.0'),
'oauth_signature='.rawurlencode($signature)
];
file_get_contents(sprintf('%s?%s', 'https://trello.com/1/OAuthGetAccessToken', implode('&', $params)));