はじめに

#2013/12/30 初版
#2014/5/25  実装修正

CakePHPにはAuthコンポーネントというものがあります。
Authコンポーネントの認証クラスを作成し、Facebook認証をします。

Facebook SDK

以下からFacebook SDKをダウンロード
https://developers.facebook.co……ingstarted

git clone https://github.com/facebook/facebook-php-sdk

下記に配置

app/Controller/Component/Auth

Facebookアプリ登録

Developersサイトにてアプリ登録をします。
https://developers.facebook.com

※全部英語ですがなんとなくわかると思います。
Apps→Create a New App
アプリケーション名を決めてアプリケーション作成ボタンをクリック

DashboardにAppIDとAppSecretがあるのでそれをメモしておきます。

SettingにてContact Emailを登録します(これをしないと公開出来ません)

今回は、Webサイトでlocalhostなので
Setting→AddPlatform→WebSite→SiteURLに http://localhost:8888/とします。

FacebookAuthenticate.php

app/Controller/Component/Auth/FacebookAuthenticate.php

<?php
App::uses('BaseAuthenticate','Controller/Component/Auth');
App::import('Vendor','facebook',array('file'=>'facebook/src/facebook.php'));

class FacebookAuthenticate extends BaseAuthenticate {
	public $settings = array(
		'fields'=>array(
			'fbUserId'=>'fb_user_id',
			'fbToken'=>'fb_tokem',
		),
		'userModel'=>'User',
		'fbScope'=>'publish_stream,email',
	);
	
	public function authenticate(CakeRequest $request,CakeResponse $response){
		CakeLog::write('debug', '[FacebookAuthenticate/authenticate] REQUEST');
		try{
			$facebook = new Facebook(array(
				'appId'=>$this->settings['fbAppId'],
				'secret'=>$this->settings['fbAppSecret'],
				'cookie'=>true
			));
		
			switch ($request->params['action']){
				case 'fblogin':
					CakeLog::write('debug', '[FacebookAuthenticate/authenticate login] REQUEST');					
					$login_url = $facebook->getLoginUrl(array(
						'redirect_uri'=>$this->settings['fbRedirect'],
						'scope'=>$this->settings['fbScope'],
					));
					$response->header('Location',$login_url);
					$response->send();
					break;
				case 'callback':
					CakeLog::write('debug', '[FacebookAuthenticate/authenticate callback] REQUEST');			
					return $this->_fb_update_user(
						$user_id = $facebook->getUser(),
						$facebook->getAccessToken()
					);
					break;				
			}
		} catch(OAuthException $e){
			CakeLog::write('debug', '[FacebookAuthenticate/authenticate OAuthException] REQUEST');					
			debug($e);
		}
	}
	
	public function _fb_update_user($user_id,$token){
		CakeLog::write('debug', '[FacebookAuthenticate/_fb_update_user($user_id,$token)] REQUEST');					
		$fields = $this->settings['fields'];
		$model_name = $this->settings['userModel'];
		
		$model = ClassRegistry::init($model_name);
		$user = $model->find(
			'first',
			array(
				'conditions'=>array(
					$model_name.'.'.$fields['fbUserId']=>$user_id
				),
			'recursive'=>0
			)
		);
		
		if(empty($user)||empty($user[$model_name])){
			CakeLog::write('debug', '[FacebookAuthenticate/_fb_update_user($user_id,$token) empty($user)||empty($user[$model_name])] REQUEST');					
			$model->create();
			$user = array(
				$model_name => array(
					$fields['fbUserId']=>$user_id,
					$fields['fbToken']=>$token,
			));
		}else{
			CakeLog::write('debug', '[FacebookAuthenticate/_fb_update_user($user_id,$token) else REQUEST');					
			$user[$model_name][$fields['fbToken']]=$token;
		}
		return $model->save($user);
	}				
}

UsersController.php

app/Controller/UsersController.php

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

class UsersController extends AppController{
	public $name = 'Users';
	public $uses = array('User');
	public $components = array(
		'Auth' => array(
			'authenticate' => array(
				'Form'=>array(
					'fields'=>array(
						'username'=>'email',
						'password'=>'password',
					),
				),
				'Facebook'=>array(
					'fbAppId'=>'****',
					'fbAppSecret'=>'****',
					'fbScope'=>'publish_stream',
					'fbRedirect'=>'http://localhost:8888/Users/callback/facebook',
					'userModel'=>'User',
					'fields'=>array(
						'fbUserId'=>'fb_user_id',
						'fbToken'=>'fb_token',
						),					
				)
			),
			'loginAction' => '/Users/login',//ログインしていない時リダイレクトさせる
			'loginRedirect' => '/events/index',
			'logoutRedirect' => '/Users/login'
		)
	);
	
	public function selectbyuserid($user_id) {
		$this->log('[UsersController/selectbyuserid] REQUEST', 'debug');	
		return $this->User->find('all',array('fields'=>array('User.email'),'conditions'=>array('User.id'=>$user_id)));
	}
	
	function beforeFilter(){
		$this->log('[UsersController/beforeFilter] REQUEST', 'debug');	
		parent::beforeFilter();
		$this->Auth->allow('callback');
	}
		
	public function index(){
		$this->log('[UsersController/index()] REQUEST', 'debug');
		$this->set('user',$this->Auth->user());
	}
	
	public function login(){
		//メールによるログイン
		$this->log('[UsersController/maillogin()/] REQUEST', 'debug');
		$errors = array();
		if($this->request->data){
			$this->log('[UsersController/maillogin()/ $this->request->data true] REQUEST', 'debug');	
			if($this->Auth->login()){
				return $this->redirect($this->Auth->redirectUrl());
			}else{
				$this->log('[UsersController/maillogin()/ $this->request->data false] REQUEST', 'debug');	
				$errors[]='メールアドレスかパスワードが違います';
			}
			$this->set('errors',$errors);
		}
	}
	
	public function fblogin(){
		//Facebookによるログイン
		$this->log('[UsersController/fblogin()] REQUEST', 'debug');	
		$user = $this->Auth->user();
		if($user){
			$this->log('[UsersController/fblogin() ログイン済 ] REQUEST', 'debug');	
			$this->redirect($this->Auth->loginRedirect);
		}else{
			$this->log('[UsersController/fblogin() ログイン未 ] REQUEST', 'debug');
			$this->Auth->login();
		}			
	}
	
	public function callback($provider){
		$this->log('[UsersController/callback()] REQUEST', 'debug');
		if($this->Auth->login()){
			$this->log('[UsersController/callback()/login true] REQUEST', 'debug');
			$this->redirect($this->Auth->redirectUrl());
		}
	}
		
	public function logout(){
		$this->log('[UsersController/logout()] REQUEST', 'debug');
		$logout_url = $this->Auth->logout();
		$this->redirect($logout_url);		
	}

	public function islogin(){
		$this->log('[UsersController/islogin()] REQUEST', 'debug');		
		$logged_in = $this->Auth->User();
		$logged_in = AuthComponent::User();
		if(is_null($logged_in)){
		}else{
			return $logged_in['email'];
		}		
	}	
}