hoangnguyenba / yii2-oauth2-server
PHP OAuth2 服务器
Requires
This package is not auto-updated.
Last update: 2016-06-21 12:57:37 UTC
README
OAuth2 服务器实现包装器(https://github.com/bshaffer/oauth2-server-php)
安装
推荐通过 composer 安装此扩展。
运行以下命令:
php composer.phar require --prefer-dist filsh/yii2-oauth2-server "*"
或者
"filsh/yii2-oauth2-server": "~2.0"
将以下内容添加到 composer.json 的 require 部分。
要使用此扩展,只需将以下代码添加到您的应用程序配置中的新模块
'modules'=>[
//other modules .....
'oauth2' => [
'class' => 'filsh\yii2\oauth2server\Module',
'tokenParamName' => 'accessToken',
'tokenAccessLifetime' => 3600 * 24,
'storageMap' => [
'user_credentials' => 'app\models\User',
],
'grantTypes' => [
'user_credentials' => [
'class' => 'OAuth2\GrantType\UserCredentials',
],
'refresh_token' => [
'class' => 'OAuth2\GrantType\RefreshToken',
'always_issue_new_refresh_token' => true
]
]
]
],
如果您想使用 Json Web Token (JWT) 而不是常规令牌,您需要在模块中设置 'useJwtToken' => true,然后定义另外两个配置:'public_key' => 'app\storage\PublicKeyStorage',这是实现 PublickKeyInterface 的类,以及 'access_token' => 'app\storage\JwtAccessToken',这是实现 JwtAccessTokenInterface.php 的类。
OAuth2 基础库提供默认的 access_token,它工作得很好,除了它会尝试将令牌保存到数据库中。所以我决定从它继承并覆盖尝试保存的部分(令牌大小太大,在数据库中的 VARCHAR(40) 上崩溃。
TL;DR,以下是一些示例类 access_token
<?php
namespace app\storage;
/**
*
* @author Stefano Mtangoo <mwinjilisti at gmail dot com>
*/
class JwtAccessToken extends \OAuth2\Storage\JwtAccessToken
{
public function setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope = null)
{
}
public function unsetAccessToken($access_token)
{
}
}
和 public_key
<?php
namespace app\storage;
class PublicKeyStorage implements \OAuth2\Storage\PublicKeyInterface{
private $pbk = null;
private $pvk = null;
public function __construct()
{
//files should be in same directory as this file
//keys can be generated using OpenSSL tool with command:
/*
private key:
openssl genrsa -out privkey.pem 2048
public key:
openssl rsa -in privkey.pem -pubout -out pubkey.pem
*/
$this->pbk = file_get_contents('privkey.pem', true);
$this->pvk = file_get_contents('pubkey.pem', true);
}
public function getPublicKey($client_id = null){
return $this->pbk;
}
public function getPrivateKey($client_id = null){
return $this->pvk;
}
public function getEncryptionAlgorithm($client_id = null){
return 'HS256';
}
}
注意:您需要应用 这个PR 或者您可以通过检查 这个diff 来自行打补丁。PR的其余部分仅适用于您想使用Firebase JWT库(实际上并非强制)。
此外,扩展 common\models\User - 用户模型 - 实现 \OAuth2\Storage\UserCredentialsInterface 接口,以便将 oauth2 凭据数据存储在用户表中。您应该实现以下方法:
- findIdentityByAccessToken()
- checkUserCredentials()
- getUserDetails()
您可以选择扩展模型(请记住更新配置文件)。
use Yii;
class User extends common\models\User implements \OAuth2\Storage\UserCredentialsInterface
{
/**
* Implemented for Oauth2 Interface
*/
public static function findIdentityByAccessToken($token, $type = null)
{
/** @var \filsh\yii2\oauth2server\Module $module */
$module = Yii::$app->getModule('oauth2');
$token = $module->getServer()->getResourceController()->getToken();
return !empty($token['user_id'])
? static::findIdentity($token['user_id'])
: null;
}
/**
* Implemented for Oauth2 Interface
*/
public function checkUserCredentials($username, $password)
{
$user = static::findByUsername($username);
if (empty($user)) {
return false;
}
return $user->validatePassword($password);
}
/**
* Implemented for Oauth2 Interface
*/
public function getUserDetails($username)
{
$user = static::findByUsername($username);
return ['user_id' => $user->getId()];
}
}
下一步,您应该运行迁移
yii migrate --migrationPath=@vendor/filsh/yii2-oauth2-server/migrations
此迁移创建 oauth2 数据库模式和插入测试用户凭据 testclient:testpass,用于 http://fake/
添加 URL 规则到 urlManager
'urlManager' => [
'enablePrettyUrl' => true, //only if you want to use petty URLs
'rules' => [
'POST oauth2/<action:\w+>' => 'oauth2/rest/<action>',
...
]
]
使用
要使用此扩展,只需为您的基控制器添加行为
use yii\helpers\ArrayHelper;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\QueryParamAuth;
use filsh\yii2\oauth2server\filters\ErrorToExceptionFilter;
use filsh\yii2\oauth2server\filters\auth\CompositeAuth;
class Controller extends \yii\rest\Controller
{
/**
* @inheritdoc
*/
public function behaviors()
{
return ArrayHelper::merge(parent::behaviors(), [
'authenticator' => [
'class' => CompositeAuth::className(),
'authMethods' => [
['class' => HttpBearerAuth::className()],
['class' => QueryParamAuth::className(), 'tokenParam' => 'accessToken'],
]
],
'exceptionFilter' => [
'class' => ErrorToExceptionFilter::className()
],
]);
}
}
获取访问令牌(js示例)
var url = window.location.host + "/oauth2/token";
var data = {
'grant_type':'password',
'username':'<some login from your user table>',
'password':'<real pass>',
'client_id':'testclient',
'client_secret':'testpass'
};
//ajax POST `data` to `url` here
//