symfonyでつくったウェブサイトでtwitterを使ってログインするようにしてみた。自分でphp-twientというライブラリをつくっておいてもともとクライアント(bot)用だったのとOAuthも忘れてしまっていたので備忘録メモ。
復習。
http://oauth.net/core/1.0/#anchor9
http://oauth.net/core/1.0/#auth_step2
まず、サイトをtwitterにアプリケーション登録する。
http://twitter.com/oauth_clients
サイトなのでApplication TypeをBrowserにして、さらにログインに使うのでYes, use Twitter for login にチェックを入れる。
ここからsymfonyによる開発。今回のメモの実績はsymfony 1.4.2 (sandbox)。
twitterにアプリケーション登録して取得したキーを
/apps/frontend/config/app.yml
に書く
all:
twitter:
consumer_key: ’your twitter consumer key'
consumer_secret: 'your twitter consumer securet'
次にphp-twientを取得して配置する
/path-to-sf_project/lib/vendor/php-twient
php-twientはautoload機能を持っているがとりあえずsymfonyにやらせる
apps/frontend/config/autoload.yml
をつくって以下を書く
autoload:
php-twient:
name: php-twient
path: %SF_LIB_DIR%/vendor/php-twient/src
recursive: on
認証の処理を担当するモジュールを作成する、とりあえずoauthという名前にする
# php symfony generate:module frontend oauth
oauth/twitterというURLで認証実行、oauth/twitter_returnというURLでtwitterからのcallbackを処理する。すなわち
/apps/frontend/modules/oauth/actions/actions.class.php
にexecuteTwitterメソッド,executeTwitter_returnメソッドをそれぞれ実装する
処理の流れとしては
executeTwitter
1) Twitter::oAuth()でサイトのConsumerキーを渡してTwitter_Auth_OAuthを取得
2) Twitter_Auth_OAuth::getRequestTokenにてcallbackを指定してリクエストを投げる
(アプリケーション登録したcallbackとは別のものも指定できるので開発時は重宝する)
3) 成功するとユーザのauthTokenが手に入るのでTwitter_Auth_OAuth::getAuthorizeUrlで認証URLを取得し飛ばす。コールバックに戻ってきたときに使うので一旦このtokenはセッションに入れとく
4) twitterの認証URLでごにょごにょしてユーザが許可したらcallbackのURLに戻ってくる(executeTwitter_returnが実行される)
executeTwitter_return
1) Twitter::oAuthで今度はConsumerキーとセッションに入れてたtokenを使ってTwitter_Auth_OAuthを取得
2) twitterからもらったoauth_verifierをつかってTwitter_Auth_OAuth::getAccessTokenを呼び出す
3) twitter_idを取得できたのでこれをユーザのIDとしてログイン済みとする
コード
class oauthActions extends sfActions
{
public function executeTwitter(sfWebRequest $request)
{
sfContext::getInstance()->getConfiguration()->loadHelpers(array('Url'));
$twitter = new Twitter();
$auth = $twitter->oAuth(sfConfig::get('app_twitter_consumer_key'),sfConfig::get('app_twitter_consumer_secret'));
$token = $auth->getRequestToken(url_for('oauth/twitter_return',true));
if ($token['oauth_callback_confirmed']) {
$this->getUser()->setAttribute('oauth_token',$token);
$this->redirect($auth->getAuthorizeUrl($token));
}
return sfView::NONE;
}
public function executeTwitter_return(sfWebRequest $request)
{
$oauth_token = $request->getParameter('oauth_token');
$oauth_verifier = $request->getParameter('oauth_verifier');
$token = $this->getUser()->getAttribute('oauth_token');
if (!$token || $token['oauth_token'] != $oauth_token) {
return sfView::ERROR;
}
$twitter = new Twitter();
$auth = $twitter->oAuth(
sfConfig::get('app_twitter_consumer_key'),
sfConfig::get('app_twitter_consumer_secret'),
$token['oauth_token'],
$token['oauth_token_secret']);
$token = $auth->getAccessToken($oauth_verifier);
$this->getUser()->setAuthenticated(true);
$this->getUser()->setAttribute('twitter_id', $token['user_id']);
$this->getUser()->setAttribute('twitter_account', $token['screen_name']);
return sfView::NONE;
}
}
一応php_twientうごいた。ほっ。symfonyなんか知らんって人でも$request->getParameterを$_REQUEST,
$this->getUser()->getAttribute, $this->getUser()->setAttributeを$_SESSIONに脳内変換してもらえればだいたいわかるはず。
php_twientはエラーは例外吐くので適当にtry-catchしてエラーページ表示してください。