cakePHPでTwitterAPIのOAuth認証を実装してみる
2016-06-07cakePHP のプロジェクト内で Twitter API を使用できるようにしたときのメモです。
準備
フレームワークはcakePHPを使用します。 TwitterAPIのライブラリとして、 OAuth consumers for CakePHP を使用します。 こちら からzipファイルをダウンロードして、中にある OAuthフォルダを**app/Vender/**に配置します。
構成
あくまでも例ですが。
OAuth認証も含めて、その他TwitterAPIで使用する機能(ツイート、タイムライン取得など)のメソッドをTwitterCompornent.phpに記載して、各コントローラーからそれを使うというイメージです。
実装例
TwitterCompornent.php
<?php
// OAuth consumersの読み込み
App::import('Vendor', 'OAuth/OAuthClient');
class TwitterComponent extends Component {
public function initialize( Controller $controller )
{
$this->Controller = $controller;
}
/** アプリケーションのConsumer Key (API Key) */
const TWITTER_CK = 'CK1234567890';
/** アプリケーションのConsumer Secret (API Secret) */
const TWITTER_CS = 'CS1234567890';
/** アプリケーションのCallback URL */
const TWITTER_CALLBACK_URL = 'http://www.example.com/test/callback';
/** アクセストークン取得 **/
const URL_OAUTH_ACCESS_TOKEN = 'https://api.twitter.com/oauth/access_token';
/** リクエストトークン取得 **/
const URL_OAUTH_REQUEST_TOKEN = 'https://api.twitter.com/oauth/request_token';
/**
* ユーザー認証を行う
* return array
*/
public function authorizeUser()
{
// Twitterオブジェクト作成
$twitterOauthObj = $this->__createClient( self::TWITTER_CK, self::TWITTER_CS );
$twitterOauthToken = $twitterOauthObj->post(
self::TWITTER_AT,
self::TWITTER_AS,
self::URL_OAUTH_REQUEST_TOKEN,
array(
'oauth_callback' => rawurldecode( self::TWITTER_CALLBACK_URL )
)
);
if ( $twitterOauthToken->headers[ 'status' ] != '200 OK' )
{
return false;
}
else
{
$return_params = explode( '&', $twitterOauthToken->body );
$oauth_info = array();
foreach ( $return_params as $p )
{
$p_tmp = explode( '=', $p );
if ( $p_tmp[ 0 ] == 'oauth_callback_confirmed' )
{
$oauth_info[ $p_tmp[ 0 ] ] = ( $p_tmp[ 1 ] == 'true' ) ? true : false;
}
else
{
$oauth_info[ $p_tmp[ 0 ] ] = $p_tmp[ 1 ];
}
}
}
// 認証用URL生成
$authenticate_url = sprintf( 'https://api.twitter.com/oauth/authenticate?oauth_token=%s', $oauth_info[ 'oauth_token' ] );
$reutrn_array = array(
'authenticate_url' => $authenticate_url,
'user_oauth_session' => $oauth_info
);
return $reutrn_array;
}
/**
* アクセストークンを取得する
* @param String $request_token
* @param String $request_token_secret
* @param String $oauth_verifier
* @return array
*/
public function criateAccessToken( $request_token, $request_token_secret, $oauth_verifier )
{
// Twitterオブジェクト作成
$twitterOauthObj = $this->__createClient( self::TWITTER_CK, self::TWITTER_CS );
$res = $twitterOauthObj->post(
$request_token,
$request_token_secret,
self::URL_OAUTH_ACCESS_TOKEN,
array(
'oauth_verifier' => $oauth_verifier
)
);
// レスポンスを配列に変換
$return_params = explode( '&', $res->body );
$oauth_info = array();
foreach ( $return_params as $p )
{
$p_tmp = explode( '=', $p );
$oauth_info[ $p_tmp[ 0 ] ] = $p_tmp[ 1 ];
}
return $oauth_info;
}
/**
* インスタンス作成
* @param String $ck
* @param String $cs
* @return OAuthClient
*/
protected function _createClient( $ck, $cs )
{
return new OAuthClient(
$ck, //Consumer key
$cs //Consumer secret
);
}
}
TestController.php
<?php
class TestController extends AppController
{
public $components = array( 'Twitter' );
function __construct ( $request, $response )
{
parent::__construct( $request, $response );
}
/**
* ログイン
*/
public function login ()
{
$this->autoRender = false;
// ユーザー認証
$res = $this->Twitter->authorizeUser();
if ( $res == false )
{
$this->redirect( '/' );
}
else
{
// セッション登録
$this->Session->write( 'user_oauth', $res[ 'user_oauth_session' ] );
// 認証ページヘリダイレクト
$this->redirect( $res[ 'authenticate_url' ] );
}
}
/**
* コールバック
*/
public function callback ()
{
$this->autoRender = false;
try
{
// 認証キャンセルの場合はセッションを削除してトップページへ
if ( isset( $this->params->query[ 'denied' ] ) )
{
if ( $this->Session->check( 'user_oauth' ) )
{
$this->Session->delete( 'user_oauth' );
}
$this->redirect( '/' );
}
// セッション情報取得
if ( !$this->Session->check( 'user_oauth' ) )
{
throw new Exception( 'セッション情報を取得できませんでした。' );
}
$user_oauth_session = $this->Session->read( 'user_oauth' );
// Twitterから返却されたOAuthトークンとセッションに保存されたOAuthトークンを比較
$retutn_oauth_token = ( isset( $this->params->query[ 'oauth_token' ] ) ) ? $this->params->query[ 'oauth_token' ] : null;
if ( $retutn_oauth_token != $user_oauth_session[ 'oauth_token' ] )
{
// セッション削除
$this->Session->delete( 'user_oauth' );
throw new Exception( 'OAuthトークンが無効です。' );
}
// アクセストークンを取得する
$access_token = $this->Twitter->criateAccessToken( $user_oauth_session[ 'oauth_token' ], $user_oauth_session[ 'oauth_token_secret' ], $this->params->query[ 'oauth_verifier' ] );
if ( !$access_token )
{
// セッション削除
$this->Session->delete( 'user_oauth' );
throw new Exception( 'アクセストークンが取得できませんでした。' );
}
// セッションに保存
$user_oauth_session[ 'access_token' ] = $access_token;
$this->Session->write( 'user_oauth', $user_oauth_session );
// トップページヘリダイレクト
$this->redirect( '/' );
}
catch ( Exception $e )
{
$this->log( $e->getMessage() );
}
}
}
認証処理が成功すると、セッション情報として以下の形で oauth_token、 oauth_token_secretがそれぞれ取得できます。
<?php
$user_oauth_session = array(
'access_token' => array(
'oauth_token' => 'OT1234567890',
'oauth_token_secret' => 'OTS1234567890'
)
);
あとはこの2つの値を使ってTwitterAPIを利用することになります。
ちなみに、この方法で実装したアプリケーションがこちらです。 ただ「やっほ〜!」とつぶやくだけ 文字通り、ただやっほ〜とつぶやくだけです。一応つぶやいた数をカウントしているので、どんどんつぶやいてみてください。
comments powered by Disqus