Le but de ce mini tutorial est d’implémenter la fonctionnalité single sign-on de Twitter sur un site construit autour de Symfony. Pour ce faire, j’ai utilisé la bibliothèque Yapl4twitter (que j’ai développé).
On n’oubliera pas de consulter Sign in with twitter afin de mieux comprendre comment fonctionne cette fonctionnalité.
Un article où il y a plus de code que de texte, mais je pense que c’est assez clair. ;-)
Installer Yapl4twitter et le configurer
$ git clone git://github.com/mycroft/yapl4twitter.git
[...]
On le rajoute dans config/autoload.yml pour que les classes soient préloadées:
twitter:
name: twitter
path: %SF_LIB_DIR%/vendor/yapl4twitter
recursive: off
On va ensuite avoir besoin de clefs valide d’une application. On prendra donc soin d’en créer une sur https://dev.twitter.com/apps et de créer le config/app.yml adéquat:
base_url: http://mysite.com
twitter:
consumer_key: <Consumer key>
consumer_secret: <Consumer secret>
request_token_url: https://api.twitter.com/oauth/request_token
access_token_url: https://api.twitter.com/oauth/access_token
authorize_url: https://api.twitter.com/oauth/authorize
authenticate_url: https://api.twitter.com/oauth/authenticate
Le module et ses actions dans symfony
On crée un module spécifique au login/logout. Mon application s’appelle « frontend », tout simplement:
On aura dans ce module deux actions: login et logout. On n’oubliera pas d’en créer les routes dans apps/frontend/config/routing.yml:
url: /login
param: { module: twitter, action: login }
logout:
url: /logout
param: { module: twitter, action: logout }
Il ne reste plus qu’à implémenter les deux actions:
{
$oa = new OAuth(
sfConfig::get('app_twitter_consumer_key'),
sfConfig::get('app_twitter_consumer_secret')
);
// Premiere etape: Pas de parametre oauth_token: On ne vient pas de twitter.com
// On fait donc la demande d'un request token et on redirige l'utilisateur vers
// twitter.com.
if(FALSE == $request->hasParameter('oauth_token'))
{
$request_token_url = sfConfig::get('app_twitter_request_token_url');
$callback_url = sfConfig::get('app_base_url');
$callback_url.= $this->getController()->genUrl('@login');
$request_token = $oa->getRequestToken($request_token_url,
$callback_url);
// On redirige vers l'authenticate_url qui permet de ne pas avoir
// a accepter l'application une nouvelle fois.
$next_url = sfConfig::get('app_twitter_authenticate_url');
$next_url.= '?oauth_token=' . $request_token['oauth_token'];
$this->redirect( $next_url );
}
// Seconde etape: On a un parametre oauth_token. On vient donc de twitter.com
// On va recuperer a partir du oauth_token et oauth_verifier l'oauth_token_secret.
else
{
$oauth_token = $request->getParameter('oauth_token');
$oauth_verifier = $request->getParameter('oauth_verifier');
$access_token = $oa->getAccessToken(sfConfig::get('app_twitter_access_token_url'),
$oauth_token,
$oauth_verifier);
// On a le token, on enregistre dans la session le screen_name et
$this->getUser()->setAttribute('screen_name', $access_token['screen_name']);
$this->getUser()->setAttribute('oauth_token', $access_token['oauth_token']);
$this->getUser()->setAttribute('oauth_token_secret', $access_token['oauth_token_secret']);
$this->getUser()->setAuthenticated(TRUE);
// On pourrait avoir une table ou l'on stocke ces informations pour plus tard:
// $account = AccountTable::getInstance()->findOneByScreenName($access_token['screen_name']);
// if( ! $account )
// {
// $account = new Account();
// $account->screen_name = $access_token['screen_name'];
// $account->user_id = $access_token['user_id'];
// $account->oauth_token = $access_token['oauth_token'];
// $account->oauth_token_secret = $access_token['oauth_token_secret'];
// $account->save();
// }
// $this->getUser()->setAttribute('account_id', $account->id);
// On est loggue, on retourne sur la page principale:
$this->redirect('@homepage');
}
return sfView::NONE;
}
// logout: On invalide tout.
public function executeLogout(sfWebRequest $request)
{
$this->getUser()->setAttribute('screen_name', NULL);
$this->getUser()->setAttribute('oauth_token', NULL);
$this->getUser()->setAttribute('oauth_token_secret', NULL);
$this->getUser()->setAuthenticated(FALSE);
return $this->redirect('@homepage');
}