Я пытаюсь войти в систему только с помощью PHP и curl
без каких-либо внешних библиотек для щебет аутентификация. я следую эти инструкции 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. И я схватил verifyier_token с этим слешем.
Задача ещё не решена.
Других решений пока нет …