CakePHPでOAuthを使ったログインと自サービスのログインの両方に対応させてみました。
一人のユーザがTwitterアカウントとこちらが作成したアカウントの両方でログインできるようにする方法を実装してみました。
その際に今回、参考にさせてもらったサイトは以下の3つです。
CakePHP で OAuth 認証を使ったログイン認証・保持や会員データの保持・更新をするコードを公開します | ウェブル
"ユーザ名かメールアドレスでログイン" フォーラム - CakePHP Users in Japan
CakePHPでTwitterマッシュアップを作る#4 - BUENA VISTA SOCIAL BLOG
やることは3つくらいです。
・CakePHPのOAuth認証ライブラリ持ってきて、設置
・twitterでアプリ登録をしてcallbackのURLを設定
・コードかく
1.まず、初めにCakePHPのOAuth認証ライブラリなるものがあるので、以下のリンクからとってきて/app/vendorsに設置してください。
OAuth consumers for CakePHP - by cakebaker
2.あとはtwitterのアプリ登録してください。以下のリンクから登録できます。その際にcallbackurlの設定をしっかりしてください
Twitter Developers
3.ソースコードかく。で、書いたソースコード貼りました。
コントローラ
<?php App::import('Vendor', 'oauth', array('file' => 'OAuth'.DS.'oauth_consumer.php')); class ExamplesController extends AppController { public $uses = array('Example'); public $components = array('Auth'); public function beforefilter(){ $this->Auth->userModel = 'Example';//認証モデル設定 $this->Auth->allow('index','twitter','twitter_callback' ); $this->Auth->loginRedirect = array('controller' => 'examples','action' => 'test'); $this->Auth->logoutRedirect = array('controller' => 'examples','action' => 'logout'); $this->Auth->loginAction = '/examples/login'; if ($this->data['Example']['username'] != '' && $this->data['Example']['password'] != '') { $this->Auth->fields = array('username' => 'username', 'password' => 'password'); } else if ($this->data['Example']['access_token_key'] != '' && $this->data['Example']['access_token_secret'] != '') { $this->Auth->fields = array('username' => 'access_token_key', 'password' => 'access_token_secret'); } else { $this->Auth->fields = array('username' => 'access_token_key', 'password' => 'access_token_secret'); } parent::beforeFilter(); } public function twitter() { $consumer = $this->createConsumer(); $requestToken = $consumer->getRequestToken('http://twitter.com/oauth/request_token', '自身のサイトでコールバックしてほしいURLを設定'); $this->Session->write('twitter_request_token', $requestToken); $this->redirect('http://twitter.com/oauth/authorize?oauth_token=' . $requestToken->key); } public function twitter_callback() { $requestToken = $this->Session->read('twitter_request_token'); $consumer = $this->createConsumer(); $accessToken = $consumer->getAccessToken('http://twitter.com/oauth/access_token', $requestToken); //Twitter からユーザーデータを取得 $json = $consumer->get($accessToken->key, $accessToken->secret, 'http://twitter.com/account/verify_credentials.json', array()); $twitterData = json_decode($json, true); $this->Example->update( Array( "example_id" => $twitterData['id_str'], "example_name" => $twitterData['screen_name'], "access_token_key" => $accessToken->key, "access_token_secret" => $accessToken->secret, ) ); $this->data['Example']['access_token_key'] = $accessToken->key; $this->data['Example']['access_token_secret'] = $accessToken->secret; if ($this->Auth->login($this->data)) { $this->redirect($this->Auth->redirect()/*'/examples/test'*/); } else { $this->redirect('index'); } } public function index(){ } public function login(){ if ($this->Auth->login($this->data)) { $this->redirect($this->Auth->redirect()); } } public function logout(){ $this->Auth->logout(); $this->flash('トップページにとぶ','index'); } public function test() { $data =$this->Auth->user(); print_r($data); } private function createConsumer() { return new OAuth_Consumer('コンシューマーキー', 'シークレットキー'); } }
モデル。これは1番上のリンクのモデルと同じです。
<?php class Example extends AppModel { var $name = 'Example'; public function update($example_data) { $example = $this->find('first', array('conditions' => array('example_id' => $example_data['example_id']))); if($example) { $example_data['id'] = $example['Example']['id']; } $this->create(); $this->save(Array("Example" => $example_data)); } }
ビュー
<?php echo $html->link('ついったーでログイン','/examples/twitter'); ?> <?php echo $form->create('Example',array('controller' => 'examples','action' => 'login')); ?> <?php echo $form->input('username'); ?> <?php echo $form->input('password'); ?> <?php echo $form->end('Login'); ?>