3

我正在尝试仅使用 PHP 和 登录用户,而没有任何用于Twittercurl身份验证的外部库。我遵循这些 Twitter 说明但我不知道如何完成第 3 步。

1.获取请求令牌(完成)

2.重定向用户(完成)

3.将请求令牌转换为访问令牌。(完成*问题

这是我的代码:

    // API SETTINGS
    $consumerSecret = 'xxx';
    $consumerKey = 'xxx';
    $oauth_signature_method = 'HMAC-SHA1';

    if (!isset($_GET['oauth_verifier'])) {

        // STEP 1 - TWITTER OBTAINING A REQUEST TOKEN
        $callbackUrl = 'http://localhost/skeletons/webiik/example/login/';
        $url = 'https://api.twitter.com/oauth/request_token';

        // Data we will send
        $data = [
            'oauth_callback' => $callbackUrl,
            'oauth_consumer_key' => $consumerKey,
            'oauth_signature_method' => $oauth_signature_method,
            'oauth_timestamp' => time(),
            'oauth_nonce' => $token->generate(3),
            'oauth_version' => '1.0',
        ];

        // Sort data alphabetically, because Twitter requires that
        ksort($data);

        // Generate signature and add it to data array
        $signData = 'POST&' . urlencode($url) . '&' . urlencode(http_build_query($data));
        $secret = '';
        $signKey = urlencode($consumerSecret) . '&' . urlencode($secret);
        $data['oauth_signature'] = base64_encode(hash_hmac('sha1', $signData, $signKey, true));

        // Prepare http headers from data
        $httpHeaders = [];
        foreach ($data as $key => $value) {
            $httpHeaders[] = urlencode($key) . '="' . urlencode($value) . '"';
        }

        // Add OAuth header with all data
        $httpHeaders = 'Authorization: OAuth ' . implode(', ', $httpHeaders);

        // Send post request to Twitter API with http headers and data
        $res = $http->post($url, ['httpHeaders' => [$httpHeaders]], []);

        // If we got some error, show error message and stop
        if (count($res['err']) > 0) {
            echo $res['err'];
            exit;
        }

        // Prepare data for step 2 and 3 from Twitter's response
        parse_str($res['body'], $res);
        $oauth_callback_confirmed = $res['oauth_callback_confirmed'];
        $oauth_request_token = $res['oauth_token'];

        // Store oauth_token_secret into session, we will need it in step 3
        $this->sessions->setToSession('oauth_token_secret', $res['oauth_token_secret']);
        $this->sessions->setToSession('oauth_token', $oauth_request_token);

        // STEP 2 - REDIRECTING THE USER TO TWITTER LOGIN
        header('HTTP/1.1 302 Found');
        header('Location: https://api.twitter.com/oauth/authenticate?oauth_token=' . urlencode($oauth_request_token));
    }

    // STEP 3 - CONVERTING THE REQUEST TOKEN TO AN ACCESS TOKEN
    $url = 'https://api.twitter.com/oauth/access_token';
    $oauth_token = $_GET['oauth_token'];
    $oauth_verifier = $_GET['oauth_verifier'];

    // Data we will send
    $data = [
        'oauth_consumer_key' => $consumerKey,
        'oauth_nonce' => $token->generate(3),
        'oauth_signature_method' => $oauth_signature_method,
        'oauth_timestamp' => time(),
        'oauth_token' => $oauth_token,
        'oauth_version' => '1.0',
    ];

    // Sort data alphabetically, because Twitter requires that
    ksort($data);

    // Generate signature and add it to data array
    $signData = 'POST&' . urlencode($url) . '&' . urlencode(http_build_query($data));
    $secret = $this->sessions->getFromSession('oauth_token_secret');
    $signKey = urlencode($consumerSecret) . '&' . urlencode($secret);
    $data['oauth_signature'] = base64_encode(hash_hmac('sha1', $signData, $signKey, true));

    // Sort data also with added oauth_signature, just for sure
    ksort($data);

    // Prepare http headers from data
    $httpHeaders = [];
    foreach ($data as $key => $value) {
        $httpHeaders[] = urlencode($key) . '="' . urlencode($value) . '"';
    }

    // Add OAuth header with all data
    $httpHeaders = ['Authorization: OAuth ' . implode(', ', $httpHeaders)];
    $httpHeaders[] = 'Content-Length: ' . strlen('oauth_verifier=' . urlencode($oauth_verifier));
    $httpHeaders[] = 'Content-Type: application/x-www-form-urlencoded';

    // Add oauth_verifier to POST data
    $postData = ['oauth_verifier' => $oauth_verifier];

    // Send post request to Twitter API with http headers and data
    $res = $http->post($url, ['httpHeaders' => $httpHeaders], $postData);

    // If we got some error, show error message and stop
    if (count($res['err']) > 0) {
        echo $res['err'];
        exit;
    }

    print_r($res);

编辑 1: $http 只是创建标准 curl 请求的对象。在第三步中,curl 请求如下所示:

$curl = curl_init($url);
curl_setopt_array($curl, [
     CURLOPT_RETURNTRANSFER => 1,
     CURLOPT_FAILONERROR => 1,
     CURLOPT_VERBOSE => 1,
     CURLOPT_HEADER => 1,
     CURLOPT_HTTPHEADER => $arrayOfHttpHeaders,
     CURLOPT_POST => 1,
     CURLOPT_POSTFIELDS => http_build_query($postData),
]);

$response = curl_exec($curl);

// Process response...

编辑 2: 我刚刚更新了代码以更准确地反映 Twitter 的示例。现在我真的不知道问题出在哪里。

编辑3: 解决方案:代码没问题。我遇到了路由器问题,它在 URL 的末尾添加了斜杠。我用那个斜线抓住了verifier_token。

4

0 回答 0