ristorantino / ext-auth
CakePHP 联邦登录/外部认证(通过 OAuth1 和 OAuth2)插件
Requires
- php: >=5.3.0
- eher/oauth: 1.0.7
This package is not auto-updated.
Last update: 2024-09-24 04:15:36 UTC
README
版权所有 © 2013 Scott Donnelly ( http://scott.donnel.ly )
遵循 MIT 许可协议。文件重新分发必须保留上述版权声明。
概要
一个用于快速、简单实现 CakePHP 2.x 联邦登录/外部认证(通过 OAuth1 和 OAuth2)的插件。
ExtAuth 设计允许您直接通过 Facebook、Twitter 和/或 Google 登录到您的 CakePHP 应用程序。任何其他支持 OAuth 1、OAuth 1a 或 OAuth 2 的提供者应该很容易添加。
ExtAuth 不提供用户模型或用户控制器。它作为一个组件提供,用于集成到您自己的(或另一个插件的)用户控制器中。以下是如何做到这一点的示例。
安装
推荐、最容易、最快安装 ExtAuth 的方法是使用 Composer。要使用 Composer 安装,请按照以下步骤操作
-
在终端中,切换到 app/ 目录。
-
如果您尚未安装 composer,请使用以下命令安装本地 composer。
curl -sS https://getcomposer.org/installer | php
或者,您可以按照以下说明进行操作:http://getcomposer.org/doc/00-intro.md#installation-nix
-
如果 app/ 中尚无 composer.json 文件,请创建一个,内容如下
{ "require": { "sc0ttyd/ext-auth": "dev-master" }, "config": { "vendor-dir": "Vendor/" } }
如果您已经有 composer.json 文件,请将其合并到其中。
-
运行以下命令
php composer.phar install
这将安装 ExtAuth 到您的 app/Plugin 文件夹,以及它的依赖项 EHER/OAuth,到 app/Vendor 文件夹。
-
在 app/Config/bootstrap.php 文件的顶部添加以下内容
require APP . '/Vendor/autoload.php'; spl_autoload_unregister(array('App', 'load')); spl_autoload_register(array('App', 'load'), true, true);
这将确保 Cake 可以找到我们刚刚安装的所有文件。有关更多信息,请参阅 http://mark-story.com/posts/view/installing-cakephp-with-composer 和 https://github.com/composer/composer/commit/c80cb76b9b5082ecc3e5b53b1050f76bb27b127b
如果您不熟悉 Composer,上面的内容可能看起来有点令人畏惧,但请相信我,如果您还不熟悉它,那么熟悉它将是非常值得的。熟悉 Composer 后,它会使事情变得容易得多。如果您选择使用更传统的技术,例如将此存储库中的文件复制到 app/Plugin/ExtAuth(或使用 git 子模块执行相同的操作)进行安装,那么您需要在 app/Vendor 目录中克隆 https://github.com/EHER/OAuth,并添加 App::Import() 语句或 'require_once' 语句到 ExtAuth/Controller/Component/AuthMechanisms/OAuth1AuthMechanism.php,以便加载 Util、Token、Consumer、Request 和 HmacSha1。
配置
-
确保插件被 CakePHP 加载。为此,在 Config/bootstrap.php 文件的底部放置行 CakePlugin::load('ExtAuth');。
-
对于您希望使用的每个登录提供者,您需要创建一个应用/项目,设置回调 URL,获取应用密钥和应用密钥,并告诉 ExtAuth 这些是什么。以下是操作步骤
Google
-
如果您还没有,请创建一个项目。
-
点击 API 访问
-
创建一个客户端ID。您需要设置重定向URI为http://example.com/auth_callback/google(将example.com替换为您的域名。您不能使用无效的顶级域名进行测试,例如example.dev,因为Google不允许这样做。您需要使用dev.example.com代替,以及您的example.com实时域名。)回调路径可以在ExtAuth组件的设置中更改。
-
在您的应用程序的Config/core.php文件中创建两行(或如果您有其他位置用于应用程序设置,则在其他位置)类似于以下内容
Configure::write('ExtAuth.Provider.Google.key', '123456789012.apps.googleusercontent.com'); Configure::write('ExtAuth.Provider.Google.secret', 'blahblahblahblahblahblah');
将配置值替换为Google API控制台中您项目的客户端ID和客户端密钥。
Twitter
-
如果您还没有,创建一个应用程序。回调URL需要设置为http://example.com/auth_callback/twitter。如果需要,可以在ExtAuth组件的设置中更改回调路径。
-
在您的应用程序的Config/core.php文件中创建两行(或如果您有其他位置用于应用程序设置,则在其他位置)类似于以下内容
Configure::write('ExtAuth.Provider.Twitter.key', 'blahblahblah'); Configure::write('ExtAuth.Provider.Twitter.secret', 'blahblahblahblahblahblah');
将配置值替换为Twitter应用程序详情标签页上的消费者密钥和消费者密钥。
-
确保在Twitter应用程序的设置中勾选了"使用Twitter登录"。
Facebook
-
如果您还没有这样做,创建一个应用程序。将"应用域名"设置为您的CakePHP站点的域名。
-
点击"带有Facebook登录的网站"。将站点URL设置为您的CakePHP站点的URL。
-
在您的应用程序的Config/core.php文件中创建两行(或如果您有其他位置用于应用程序设置,则在其他位置)类似于以下内容
Configure::write('ExtAuth.Provider.Facebook.key', '431235136634241414'); Configure::write('ExtAuth.Provider.Facebook.secret', '12344g4f3241e4d2144');
将配置值替换为Facebook上您的应用程序的应用ID和应用密钥。
用法
首先,确保您的用户控制器正在加载ExtAuth组件,以及CakePHP的Auth组件
public $components = array('ExtAuth.ExtAuth', 'Auth', 'Session');
您至少需要在用户控制器中创建两个操作。这些操作将启动身份验证并处理提供者的回调。例如
public function auth_login($provider) { $result = $this->ExtAuth->login($provider); if ($result['success']) { $this->redirect($result['redirectURL']); } else { $this->Session->setFlash($result['message']); $this->redirect($this->Auth->loginAction); } } public function auth_callback($provider) { $result = $this->ExtAuth->loginCallback($provider); if ($result['success']) { $this->__successfulExtAuth($result['profile'], $result['accessToken']); } else { $this->Session->setFlash($result['message']); $this->redirect($this->Auth->loginAction); } }
您还需要在Config/routes.php中创建两个路由,类似于以下内容
Router::connect('/auth_login/*', array( 'controller' => 'users', 'action' => 'auth_login')); Router::connect('/auth_callback/*', array( 'controller' => 'users', 'action' => 'auth_callback'));
这就完成了。我将把实现__successfulExtAuth函数的任务留给您,但您可能想要类似以下内容
private function __successfulExtAuth($incomingProfile, $accessToken) { // search for profile $this->SocialProfile->recursive = -1; $existingProfile = $this->SocialProfile->find('first', array( 'conditions' => array('oid' => $incomingProfile['oid']) )); if ($existingProfile) { // Existing profile? log the associated user in. $user = $this->User->find('first', array( 'conditions' => array('id' => $existingProfile['SocialProfile']['user_id']) )); $this->__doAuthLogin($user); } else { // New profile. if ($this->Auth->loggedIn()) { // user logged in already, attach profile to logged in user. // create social profile linked to current user $incomingProfile['user_id'] = $this->Auth->user('id'); $this->SocialProfile->save($incomingProfile); $this->Session->setFlash('Your ' . $incomingProfile['provider'] . ' account has been linked.'); $this->redirect($this->Auth->loginRedirect); } else { // no-one logged in, must be a registration. unset($incomingProfile['id']); $user = $this->User->register(array('User' => $incomingProfile)); // create social profile linked to new user $incomingProfile['user_id'] = $user['User']['id']; $incomingProfile['last_login'] = date('Y-m-d h:i:s'); $incomingProfile['access_token'] = serialize($accessToken); $this->SocialProfile->save($incomingProfile); // populate user detail fields that can be extracted // from social profile $profileData = array_intersect_key( $incomingProfile, array_flip(array( 'email', 'given_name', 'family_name', 'picture', 'gender', 'locale', 'birthday', 'raw' )) ); $this->User->setupDetail(); $this->User->UserDetail->saveSection( $user['User']['id'], array('UserDetail' => $profileData), 'User' ); // log in $this->__doAuthLogin($user); } } } private function __doAuthLogin($user) { if ($this->Auth->login($user['User'])) { $user['last_login'] = date('Y-m-d H:i:s'); $this->User->save(array('User' => $user)); $this->Session->setFlash(sprintf(__d('users', '%s you have successfully logged in'), $this->Auth->user('username'))); $this->redirect($this->Auth->loginRedirect); } }