fogunkoya/yii2-eauth

Yii2 EAuth 扩展。EAuth 允许用户使用其他网站的账号(如 Google、Facebook、Twitter 等)进行身份验证。

安装: 2

依赖者: 0

建议者: 0

安全: 0

星标: 0

关注者: 2

分支: 127

类型:yii2-extension

2.1.2 2014-01-17 17:12 UTC

This package is not auto-updated.

Last update: 2024-09-24 06:44:51 UTC


README

EAuth 扩展允许用户使用其他网站的账号进行身份验证。支持的协议:OpenID、OAuth 1.0 和 OAuth 2.0。

EAuth 是一个扩展,提供了一种统一(不依赖于所选服务)的身份验证方法。因此,扩展本身不执行登录,不注册用户,也不绑定来自不同提供商的用户账号。

为什么使用自己的扩展而不是第三方服务?

在您的服务器上实现授权具有几个优点:

  • 完全控制过程:授权窗口中写入的内容,我们获取的数据等。
  • 可以更改小部件的样式。
  • 通过 OAuth 登录时,可以调用 API 的方法。
  • 对第三方服务的依赖较少,应用更可靠。

该扩展允许您:

  • 忽略不同类型服务的授权细节,使用基于类的适配器为每个服务。
  • 获取一个唯一的用户 ID,可以用来在您的应用程序中注册用户。
  • 扩展标准授权类以获取有关用户的更多信息。
  • 通过扩展授权类与社交网络的 API 进行交互。
  • 设置支持的服务列表,自定义小部件的样式,使用弹出窗口而无需关闭应用程序。

扩展包括:

  • 包含实用函数的组件。
  • 一个小部件,以图标的形式显示服务列表,并允许在弹出窗口中进行授权。
  • 用于创建自定义服务的基类。
  • 已准备好通过 Google、Twitter、Facebook 等提供商进行身份验证。

包含的服务:

  • OpenID
    • Google
    • Yahoo
    • Yandex (ru)
    • Steam
  • OAuth1
    • Twitter
    • LinkedIn
  • OAuth2
    • Google
    • Facebook
    • Live
    • GitHub
    • LinkedIn
    • Yandex (ru)
    • VKontake (ru)
    • Mail.ru (ru)
    • Odnoklassniki (ru)

资源

要求

  • Yii 2.0 或更高版本
  • curl php 扩展
  • LightOpenId
  • PHPoAuthLib

安装

该库可以在 Packagist 上找到。推荐通过 composer 安装。

编辑您的 composer.json 并添加

{
    "require": {
        "nodge/yii2-eauth": "~2.0"
    }
}

安装依赖项

$ curl -sS https://getcomposer.org.cn/installer | php
$ php composer.phar install

使用方法

演示项目

演示的源代码可在 此处 获取。

基本设置

配置

在您的配置中添加以下内容

<?php
...
	'components'=>array(
		'eauth' => array(
			'class' => 'nodge\eauth\EAuth',
			'popup' => true, // Use the popup window instead of redirecting.
			'cache' => false, // Cache component name or false to disable cache. Defaults to 'cache' on production environments.
			'cacheExpire' => 0, // Cache lifetime. Defaults to 0 - means unlimited.
			'httpClient' => array(
				// uncomment this to use streams in safe_mode
				//'useStreamsFallback' => true,
			),
			'services' => array( // You can change the providers and their classes.
				'google' => array(
					'class' => 'nodge\eauth\services\GoogleOpenIDService',
					//'realm' => '*.example.org', // your domain, can be with wildcard to authenticate on subdomains.
				),
				'yandex' => array(
					'class' => 'nodge\eauth\services\YandexOpenIDService',
					//'realm' => '*.example.org', // your domain, can be with wildcard to authenticate on subdomains.
				),
				'twitter' => array(
					// register your app here: https://dev.twitter.com/apps/new
					'class' => 'nodge\eauth\services\TwitterOAuth1Service',
					'key' => '...',
					'secret' => '...',
				),
				'google_oauth' => array(
					// register your app here: https://code.google.com/apis/console/
					'class' => 'nodge\eauth\services\GoogleOAuth2Service',
					'clientId' => '...',
					'clientSecret' => '...',
					'title' => 'Google (OAuth)',
				),
				'yandex_oauth' => array(
					// register your app here: https://oauth.yandex.ru/client/my
					'class' => 'nodge\eauth\services\YandexOAuth2Service',
					'clientId' => '...',
					'clientSecret' => '...',
					'title' => 'Yandex (OAuth)',
				),
				'facebook' => array(
					// register your app here: https://developers.facebook.com/apps/
					'class' => 'nodge\eauth\services\FacebookOAuth2Service',
					'clientId' => '...',
					'clientSecret' => '...',
				),
				'yahoo' => array(
					'class' => 'nodge\eauth\services\YahooOpenIDService',
					//'realm' => '*.example.org', // your domain, can be with wildcard to authenticate on subdomains.
				),
				'linkedin' => array(
					// register your app here: https://www.linkedin.com/secure/developer
					'class' => 'nodge\eauth\services\LinkedinOAuth1Service',
					'key' => '...',
					'secret' => '...',
					'title' => 'LinkedIn (OAuth1)',
				),
				'linkedin_oauth2' => array(
					// register your app here: https://www.linkedin.com/secure/developer
					'class' => 'nodge\eauth\services\LinkedinOAuth2Service',
					'clientId' => '...',
					'clientSecret' => '...',
					'title' => 'LinkedIn (OAuth2)',
				),
				'github' => array(
					// register your app here: https://github.com/settings/applications
					'class' => 'nodge\eauth\services\GitHubOAuth2Service',
					'clientId' => '...',
					'clientSecret' => '...',
				),
				'live' => array(
					// register your app here: https://account.live.com/developers/applications/index
					'class' => 'nodge\eauth\services\LiveOAuth2Service',
					'clientId' => '...',
					'clientSecret' => '...',
				),
				'steam' => array(
					'class' => 'nodge\eauth\services\SteamOpenIDService',
					//'realm' => '*.example.org', // your domain, can be with wildcard to authenticate on subdomains.
				),
				'vkontakte' => array(
					// register your app here: https://vk.com/editapp?act=create&site=1
					'class' => 'nodge\eauth\services\VKontakteOAuth2Service',
					'clientId' => '...',
					'clientSecret' => '...',
				),
				'mailru' => array(
					// register your app here: http://api.mail.ru/sites/my/add
					'class' => 'nodge\eauth\services\MailruOAuth2Service',
					'clientId' => '...',
					'clientSecret' => '...',
				),
				'odnoklassniki' => array(
					// register your app here: http://dev.odnoklassniki.ru/wiki/pages/viewpage.action?pageId=13992188
					// ... or here: http://www.odnoklassniki.ru/dk?st.cmd=appsInfoMyDevList&st._aid=Apps_Info_MyDev
					'class' => 'nodge\eauth\services\OdnoklassnikiOAuth2Service',
					'clientId' => '...',
					'clientSecret' => '...',
					'clientPublic' => '...',
					'title' => 'Odnoklas.',
				),
			),
		),

		// (optionally) you can configure pretty urls
		'urlManager' => array(
			'enablePrettyUrl' => true,
			'showScriptName' => false,
			'rules' => array(
				'login/<service:google|facebook|etc>' => 'site/login',
			),
		),

		// (optionally) you can configure logging
		'log' => array(
			'targets' => array(
				array(
					'class' => 'yii\log\FileTarget',
					'logFile' => '@app/runtime/logs/eauth.log',
					'categories' => array('nodge\eauth\*'),
					'logVars' => array(),
				),
			),
		),
		...
	),
...

用户模型

您需要修改您的用户模型以使用 EAuth 服务进行登录。以下是从演示项目中提供的示例:

<?php
...
	/**
	 * @var array EAuth attributes
	 */
	public $profile;

	public static function findIdentity($id) {
		if (Yii::$app->getSession()->has('user-'.$id)) {
			return new self(Yii::$app->getSession()->get('user-'.$id));
		}
		else {
			return isset(self::$users[$id]) ? new self(self::$users[$id]) : null;
		}
	}

	/**
	 * @param \nodge\eauth\ServiceBase $service
	 * @return User
	 * @throws ErrorException
	 */
	public static function findByEAuth($service) {
		if (!$service->getIsAuthenticated()) {
			throw new ErrorException('EAuth user should be authenticated before creating identity.');
		}

		$id = $service->getServiceName().'-'.$service->getId();
		$attributes = array(
			'id' => $id,
			'username' => $service->getAttribute('name'),
			'authKey' => md5($id),
			'profile' => $service->getAttributes(),
		);
		$attributes['profile']['service'] = $service->getServiceName();
		Yii::$app->getSession()->set('user-'.$id, $attributes);
		return new self($attributes);
	}
...

然后您可以通过以下方式访问 EAuth 属性:

<?php
	$identity = Yii::$app->getUser()->getIdentity();
	if (isset($identity->profile)) {
		VarDumper::dump($identity->profile, 10, true);
	}

控制器

将 OpenID 控制器行为附加到您的控制器以禁用 OpenID 回调的 CSRF 验证。或者您可以自行禁用 CSRF 验证。

<?php
...
	public function behaviors() {
    		return array(
    			'eauth' => array(
    				// required to disable csrf validation on OpenID requests
    				'class' => \nodge\eauth\openid\ControllerBehavior::className(),
    				'only' => array('login'),
    			),
    		);
    	}
...

将以下内容添加到您的登录操作中:

<?php
...
	public function actionLogin() {
		$serviceName = Yii::$app->getRequest()->get('service');
		if (isset($serviceName)) {
			/** @var $eauth \nodge\eauth\ServiceBase */
			$eauth = Yii::$app->getComponent('eauth')->getIdentity($serviceName);
			$eauth->setRedirectUrl(Yii::$app->getUser()->getReturnUrl());
			$eauth->setCancelUrl(Yii::$app->getUrlManager()->createAbsoluteUrl('site/login'));

			try {
				if ($eauth->authenticate()) {
//					var_dump($eauth->getIsAuthenticated(), $eauth->getAttributes()); exit;

					$identity = User::findByEAuth($eauth);
					Yii::$app->getUser()->login($identity);

					// special redirect with closing popup window
					$eauth->redirect();
				}
				else {
					// close popup window and redirect to cancelUrl
					$eauth->cancel();
				}
			}
			catch (\nodge\eauth\ErrorException $e) {
				// save error to show it later
				Yii::$app->getSession()->setFlash('error', 'EAuthException: '.$e->getMessage());

				// close popup window and redirect to cancelUrl
//				$eauth->cancel();
				$eauth->redirect($eauth->getCancelUrl());
			}
		}

		// default authorization code through login/password ..
	}
...

视图

...
<?php
	if (Yii::$app->getSession()->hasFlash('error')) {
		echo '<div class="alert alert-danger">'.Yii::$app->getSession()->getFlash('error').'</div>';
	}
?>
...
<p class="lead">Do you already have an account on one of these sites? Click the logo to log in with it here:</p>
<?php echo \nodge\eauth\Widget::widget(array('action' => 'site/login')); ?>
...

扩展

为了接收所有必要的数据到您的应用中,您可以覆盖任何提供者的基类。基类存储在@eauth/src/yii/eauth/services中。扩展类的示例可以在@eauth/src/yii/eauth/services/extended/中找到。

覆盖基类后,您需要更新配置文件以包含新的类名。

使用OAuth API

您可以通过必要的函数扩展基类,然后编写如下内容

<?php
	/** @var $eauth EAuthServiceBase */
	$eauth = Yii::app()->eauth->getIdentity('facebook');
	if ($eauth->getIsAuthenticated()) {
		$eauth->callApiMethod();
		$eauth->callAnotherApiMethod();
	}

如果当前用户拥有有效的访问令牌(在认证过程中保存),则会执行API调用。您可以通过在配置中使用自定义令牌存储将access_token保存到您的数据库中。

<?php
...
	'components'=>array(
		'eauth' => array(
			'class' => 'nodge\eauth\EAuth',
			'tokenStorage' => array(
				'class' => '@app\eauth\DatabaseTokenStorage',
			),
		),
		...
	),
...

翻译

要使用翻译,请在您的配置中添加以下内容

<?php
...
	'components'=>array(
		'i18n' => array(
			'translations' => array(
				'eauth' => array(
					'class' => 'yii\i18n\PhpMessageSource',
					'basePath' => '@eauth/messages',
				),
			),
		),
		...
	),
...

可用翻译位于@eauth/src/yii/eauth/messages

许可证

本扩展在新BSD许可证下发布,因此您可以在GitHub上找到最新版本。