ristorantino/ext-auth

CakePHP 联邦登录/外部认证(通过 OAuth1 和 OAuth2)插件

安装: 91

依赖者: 1

建议者: 0

安全: 0

星标: 0

关注者: 5

分支: 11

类型:cakephp-plugin

dev-master 2013-06-14 00:45 UTC

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 安装,请按照以下步骤操作

  1. 在终端中,切换到 app/ 目录。

  2. 如果您尚未安装 composer,请使用以下命令安装本地 composer。

    curl -sS https://getcomposer.org/installer | php

    或者,您可以按照以下说明进行操作:http://getcomposer.org/doc/00-intro.md#installation-nix

  3. 如果 app/ 中尚无 composer.json 文件,请创建一个,内容如下

    	{
    		"require": {
    			"sc0ttyd/ext-auth": "dev-master"
    		},
    		"config": {
    			"vendor-dir": "Vendor/"
    		}
    	}

    如果您已经有 composer.json 文件,请将其合并到其中。

  4. 运行以下命令

    	php composer.phar install

    这将安装 ExtAuth 到您的 app/Plugin 文件夹,以及它的依赖项 EHER/OAuth,到 app/Vendor 文件夹。

  5. 在 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-composerhttps://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。

配置

  1. 确保插件被 CakePHP 加载。为此,在 Config/bootstrap.php 文件的底部放置行 CakePlugin::load('ExtAuth');。

  2. 对于您希望使用的每个登录提供者,您需要创建一个应用/项目,设置回调 URL,获取应用密钥和应用密钥,并告诉 ExtAuth 这些是什么。以下是操作步骤

    Google

    1. 浏览到 https://code.google.com/apis/console

    2. 如果您还没有,请创建一个项目。

    3. 点击 API 访问

    4. 创建一个客户端ID。您需要设置重定向URI为http://example.com/auth_callback/google(将example.com替换为您的域名。您不能使用无效的顶级域名进行测试,例如example.dev,因为Google不允许这样做。您需要使用dev.example.com代替,以及您的example.com实时域名。)回调路径可以在ExtAuth组件的设置中更改。

    5. 在您的应用程序的Config/core.php文件中创建两行(或如果您有其他位置用于应用程序设置,则在其他位置)类似于以下内容

      Configure::write('ExtAuth.Provider.Google.key', '123456789012.apps.googleusercontent.com');
      Configure::write('ExtAuth.Provider.Google.secret', 'blahblahblahblahblahblah');

      将配置值替换为Google API控制台中您项目的客户端ID和客户端密钥。

    Twitter

    1. 浏览到https://dev.twitter.com/apps

    2. 如果您还没有,创建一个应用程序。回调URL需要设置为http://example.com/auth_callback/twitter。如果需要,可以在ExtAuth组件的设置中更改回调路径。

    3. 在您的应用程序的Config/core.php文件中创建两行(或如果您有其他位置用于应用程序设置,则在其他位置)类似于以下内容

      Configure::write('ExtAuth.Provider.Twitter.key', 'blahblahblah');
      Configure::write('ExtAuth.Provider.Twitter.secret', 'blahblahblahblahblahblah');

      将配置值替换为Twitter应用程序详情标签页上的消费者密钥和消费者密钥。

    4. 确保在Twitter应用程序的设置中勾选了"使用Twitter登录"。

    Facebook

    1. 浏览到https://developers.facebook.com/apps

    2. 如果您还没有这样做,创建一个应用程序。将"应用域名"设置为您的CakePHP站点的域名。

    3. 点击"带有Facebook登录的网站"。将站点URL设置为您的CakePHP站点的URL。

    4. 在您的应用程序的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);
	}
}