CakePHP2.0+FacebookSDKを利用した認証(Authコンポーネントとの連携)

前回の続き、今回はAuthコンポーネントと連携してみた

  1. facebook SDKのダウンロード
  2. CakePHP内への設置
  3. Facebook用コンポーネントの作成・設定

前回のものを参照

4.テーブル作成

facebookのアカウントを蓄積するDBテーブルを作成。ここではuser_listとする。

CREATE TABLE IF NOT EXISTS `user_list` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(512) NOT NULL,
  `pw` varchar(512) DEFAULT NULL,
  `user_name` varchar(512) NOT NULL DEFAULT '名無し@guest',
  `role` varchar(64) NOT NULL,
  `modified` datetime NOT NULL,
  `created` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 ;

ユーザー名は自サイト内で設定できるようにしたかったので、user_nameカラムを追加し、facebook認証と通常のform認証で権限を変えたかったのでroleを設定することにした。

5.モデルの作成

先ほど作成したDBテーブルにアクセスするためのモデルUserを作成

<?php
class User extends AppModel {
  public $name     = 'User';
  public $useTable = 'user_list';
}

6.Authコンポーネントの設定

共通処理が必要なので、AppControllerで設定

<?php
App::uses('Controller', 'Controller');

class AppController extends Controller {
  public $components = array('Session','Auth','Facebook');

  public function beforeFilter() {
    parent::beforeFilter();

    $this->Auth->loginError     = 'IDまたはパスワードが違います';
    $this->Auth->authError      = '再度ログインしてください';
    $this->Auth->authenticate   = array('Form' =>
                                  array('userModel' => 'User',
                                        'fields'    => array('username' => 'user_id', 'password' => 'pw'))
                                  );
    $this->Auth->loginAction    = array('controller' => 'account', 'action' => 'login');
    $this->Auth->loginRedirect  = array('controller' => 'index', 'action' => 'index');
    $this->Auth->logoutRedirect = array('controller' => 'index', 'action' => 'index');
    if ($this->Auth->user()) {
      $this->set('user',$this->Auth->user());  
    }
  }
}

7.ログイン/ログアウト制御用コントローラの設定

<?php
class AccountController extends AppController {

  public $uses = array('User');

  public function login() {
    $accessToken  = $this->Facebook->getAccessToken();
    $requestToken = $this->Facebook->getRequestToken();

    $this->request->data['User']['user_id'] = $requestToken;
    $this->request->data['User']['pw']      = $accessToken;
    $this->request->data['User']['role']    = 'facebook';

    if ($requestToken) {
      $registedResult = $this->User->find('first',array('conditions' => array('user_id' => $requestToken,'pw' => AuthComponent::password($accessToken))));
      if (!$registedResult) {
        $data = array();
        $data['user_id'] = $this->request->data['User']['user_id'];
        $data['pw']      = AuthComponent::password($accessToken);
        $data['role']    = $this->request->data['User']['role'];
        if (!$this->User->save($data)) {
          throw new MissingDatabaseException();
        }
      }
      if ($this->Auth->login()) {
        return $this->redirect($this->Auth->redirect());
      }
      else {
        $this->Session->setFlash(__('認証失敗。'), 'default', array(), 'auth');
      }
    }
    else {
      //ログインページにログイン用URLを設定
      $this->set('loginUrl',$this->Facebook->getLoginUrl());
    }
  }

  public function logout() {
    $this->redirect($this->Auth->logout());
  }
}

accessTokenをパスワード、requestTokenをユーザーIDとした。
※パスワードはAuthComponent::passwordをすることを忘れずに!

もっとうまいやり方がありそうだなぁ。