Twitter APIでアカウント認証してアクセストークン取得するサンプル
PHPでTwitterのOAuth認証をする方法。
アプリ開発者自身のアクセストークンは、Twitterのアプリ管理画面の『Keys and Access Tokens』から簡単に発行できます。
が、自分のアカウントを介して何かするアプリならそれでいいけど、例えば開発者アカで作ったbotアプリをbot用の別アカウントに認証させようと思ったら、面倒です。なので、認証してアクセストークンを表示するだけのサンプルを書いてみました。
このページのサンプルの挙動は以下の通りです。
/oauth/request_token
を叩いてリクエストトークン取得し、Twitter認証ページへのリンクを表示する。- リンク先でTwitterの認証を完了すると、コールバックURLとして設定済み (※後述・要設定) のこのスクリプトに戻ってくる。
- 戻ってくる時に連れてきたGETパラメータ
oauth_verifier
を使って/oauth/access_token
を叩き、アクセストークンを取得して表示する。
<?php
const CONSUMER_KEY = '!! Consumer Key (API Key) を入力 !!';
const CONSUMER_SECRET = '!! Consumer Secret (API Secret) を入力 !!';
session_set_cookie_params(600);
session_start();
try {
if (empty($_GET)) {
//--------------------------------------
// 1. 最初にアクセスした時
//--------------------------------------
// セッション削除
unset($_SESSION['oauth_token']);
unset($_SESSION['oauth_token_secret']);
// APIを叩いてリクエストトークン取得して、セッションに保存
$res = post(
'https://api.twitter.com/oauth/request_token',
[
'oauth_callback' => '', // localhostだとこれは使えないらしいのでカラ。
]
);
if (!isset($res['oauth_token'])) {
throw new Exception('レスポンス→ '.var_export($res, true));
}
$_SESSION['oauth_token'] = $res['oauth_token'];
$_SESSION['oauth_token_secret'] = $res['oauth_token_secret'];
// リクエストトークンを持ってTiwtterの認証画面に行くリンクを表示
header('Content-Type: text/html');
$url = 'https://api.twitter.com/oauth/authenticate?oauth_token='.$res['oauth_token'];
echo '<a href="'.$url.'">'.$url.'</a>';
}
else {
//--------------------------------------
// 2. Twitterで認証して戻ってきた時
//--------------------------------------
// もらったパラメータ『oauth_verifier』をつけてAPIを叩き、アクセストークン取得
$res = post(
'https://api.twitter.com/oauth/access_token',
[
'oauth_verifier' => $_GET['oauth_verifier'],
],
$_SESSION['oauth_token'], // セッションに保存していたリクエストトークンを署名に使う
$_SESSION['oauth_token_secret'] // 同上
);
if (!isset($res['oauth_token'])) {
throw new Exception('レスポンス→ '.var_export($res, true));
}
// アクセストークンを画面に表示
header('Content-Type: text/html');
echo implode([
'成功!',
'Access Token: '.$res['oauth_token'],
'Access Token Secret: '.$res['oauth_token_secret'],
'User ID: '.$res['user_id'],
'Screen Name: '.$res['screen_name'],
], '<br />');
}
}
catch (Exception $e) {
header('Content-Type: text/plain');
echo '失敗!: '.$e->getMessage();
}
/**
* 対象URLにOAuthの署名つきでPOSTし、結果を連想配列で返却する
*/
function post($url, $params, $token = null, $secret = null) {
// curlでPOST
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => [
createOAuthHeader($url, $params, $token, $secret)
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($params),
]);
if (($res = curl_exec($ch)) === false) {
throw new Exception('通信時にエラーが発生しました。');
}
curl_close($ch);
parse_str($res, $resArr);
return $resArr;
}
/**
* OAuth用のヘッダを作成して返却する
*/
function createOAuthHeader($url, $params, $token, $secret) {
$sigparams = [
'oauth_consumer_key' => CONSUMER_KEY,
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_timestamp' => time(),
'oauth_nonce' => md5(uniqid(rand(), true)),
'oauth_version' => '1.0',
];
if (isset($token)) {
// リクエストトークンがあればセット
$sigparams['oauth_token'] = $token;
}
$sigparams += $params;
// ルール通りに署名を作成してセット
// https://developer.twitter.com/en/docs/basics/authentication/guides/creating-a-signature.html
ksort($sigparams);
$data = 'POST&'.rawurlencode($url).'&'.rawurlencode(http_build_query($sigparams, '', '&', PHP_QUERY_RFC3986)); // ここでは関係無いが、パラメータにスペースが含まれてる時用にRFC3986を明示的に指定
$key = rawurlencode(CONSUMER_SECRET).'&';
$key .= isset($secret) ? rawurlencode($secret) : ''; // リクエストトークンがあればセット
$hash = hash_hmac('sha1', $data, $key, true);
$sigparams['oauth_signature'] = base64_encode($hash);
// ヘッダ文字列にして返却
return 'Authorization: OAuth '.http_build_query($sigparams, '', ',');
}
それにしても、APIを叩くときに作る署名がとにかく面倒くさいです。ちょっと間違えるとすぐ {"code":32,"message":"Could not authenticate you."}
エラーになるし。
動かし方
最初に準備が必要です。
- ↑のソースコードをローカルサーバー上に置く。ここではファイル名
auth.php
とし、ローカルサーバー上のURLはhttp://localhost/auth.php
とする。 - アプリ管理画面の『Keys and Access Tokens』で『Consumer Key』『Consumer Secret』を確認し、ソースコード先頭の定数
CONSUMER_KEY
CONSUMER_SECRET
にそれぞれ設定する。 - アプリ管理画面の『Settings』の『Callback URLs』に
http://localhost/auth.php
を設定する。
『Callback URLs』は、Twitterに飛ばされて認証した後に戻されるページのURL (コールバックURL) です。設定画面下部の『Update Settings』ボタンを押して反映するのを忘れないように。アクセストークンをメモった後はこの設定を消して大丈夫です。
準備を行ったら、以下の通りに動かします。
- Cookieが有効なブラウザで、
http://localhost/auth.php
にアクセスする。Twitterの認証画面のURLリンクが表示されるのでクリック。 - Twitterの認証画面に飛ぶので、アクセストークンが欲しいアカウントでログインして認証する。
- 認証完了後、元の画面に戻ってくる。アクセストークンが表示されていれば成功。
成功すると、↓こんな感じの画面になります。