clement/yii-rest-rbac
Composer 安装命令:
composer require clement/yii-rest-rbac
包简介
rest rbac for yii
README 文档
README
写在前面
本篇只讲述如何使用Yii-rest-rbac进行 restful API认证和权限管理,关于原理,请移步
Yii-REST-RBAC原理(目前未完成)
下载安装
composer require clement/yii-rest-rbac
or
php composer.phar require clement/yii-rest-rbac
创建数据表
- 使用
@vendor\\clement\\yii-rest-rbac\\migrations下的yii-rest-rbac.sql导入到数据库中 - 你可以修改
表前缀cc_或者在数据库配置中添加
'tablePrefix' =>'cc_',
配置文件
- 在
app(backend/ common )的main.php中添加
'modules' => [
"admin" => [
"class" => "clement\\rest\Module",
'layout' => 'left-menu',//yii2-admin的导航菜单
],
],
"aliases" => [
"@clement/rest" => "@vendor/clement/yii-rest-rbac",
],
'components' => [
'jwt' => [
'class' => 'clement\rest\auth\Jwt',
'key' => 'xxx', // 你自己的想使用的key,注意保密
],
'user' => [
'identityClass' =>'xxxx\User',//自己的User model
'enableAutoLogin' => true,
'enableSession' =>false,
'loginUrl' => null, // api ++
],
"authManager" => [
"class" => 'clement\\rest\components\DbManager',
'defaultRoles' => ['游客'], //添加此行代码,指定默认规则为 '未登录用户'
],
/**
* 根据需要设置有无,具体的参照 yii-rest-rbac原理文档
*
*/
'as access' => [
'class' => 'clement\\rest\components\AccessControl',
'allowActions' => [
'*',//根据自己的情况设置
]
- 在
User中添加以下函数 (==注意函数中xxx参数需要自己修改==)
/**
* {@inheritdoc}
*/
public function loginByAccessToken($token, $type = null)
{
return static::findIdentityByAccessToken($token, $type);
}
/**
* Validates access_token.
*
* @param string $token token to validate
*
* @return bool if token provided is valid for current user
*/
public static function isAccessTokenValid($token)
{
if (empty($token)) {
return false;
}
$data = Yii::$app->jwt->getValidationData(); // It will use the current time to validate (iat, nbf and exp)
$data->setIssuer('xxxx1'); //xxxx1 自己填
$data->setAudience('xxxx2'); // xxxx2 自己填
$data->setId('xxxx3', true); // xxxx3 自己填
if (is_string($token))
$token = Yii::$app->jwt->getParser()->parse($token);
return $token->validate($data);
}
/**
* Generates new api access token.
*/
public function generateAccessToken()
{
// $this->access_token = Yii::$app->security->generateRandomString() . '_' . time();
$signer = new Sha256();
$token = Yii::$app->jwt->getBuilder()->setIssuer('xxxx1')// Configures the issuer (iss claim) //对应上面 xxxx1
->setAudience('xxxx2')// Configures the audience (aud claim) // 对应于上面的 xxxx2
->setId('xxxx3', true) //对应于上面的 xxxx3
->setExpiration(time() + Yii::$app->params['accessTokenExpire'])// Configures exp time
->setIssuedAt(time())// Configures the time that the token was issue (iat claim)
->sign($signer, Yii::$app->jwt->key)
->getToken(); // Retrieves the generated token
$this->access_token = (string)$token;
}
/**
* findIdentityByAccessToken find User Identity
*
*/
public static function findIdentityByAccessToken($token, $type = null)
{
// if token is not valid
if (!static::isAccessTokenValid($token)) {
throw new \yii\web\UnauthorizedHttpException('token is invalid.');
}
return static::findOne(['access_token' => $token, 'status' => self::STATUS_ACTIVE]);
// throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}
- 在
LoginForm中添加
const GET_ACCESS_TOKEN = 'generate_access_token';
public function init()
{
parent::init();
$this->on(self::GET_ACCESS_TOKEN, [$this, 'onGenerateAccessToken']);
}
/**
* Logs in a user using the provided username and password.
*
* @return boolean whether the user is logged in successfully
*/
public function login()
{
if ($this->validate()) {
$this->trigger(self::GET_ACCESS_TOKEN);
return $this->_user;
} else {
return null;
}
}
/**
* 登录校验成功后,为用户生成新的token
* 如果token失效,则重新生成token
*/
public function onGenerateAccessToken()
{
if (!User::isAccessTokenValid($this->_user->access_token)) {
$this->_user->generateAccessToken();
$this->_user->save(false);
}
}
- 使用认证
- 创建所有
api控制器基类
use clement\rest\auth\APIAuth;
use clement\rest\components\AccessControl;
class BaseController extends ActiveController
{
/**
* 设置返回头部的allow部分
* @param array $collection allow的方法集合
*/
public function ResponseOptions($collection = [])
{
$collectionOptions = ['GET', 'POST', 'HEAD', 'OPTIONS'];
if(!empty($collection)){
$collectionOptions = $collection;
}
Yii::$app->getResponse()->getHeaders()->set('Allow', implode(', ', $collectionOptions));
}
public function behaviors()
{
$behaviors = parent::behaviors();
// add CORS filter
// 处理跨域请求,注意设置生产版本的 Origin
$behaviors['corsFilter'] = [
'class' => Cors::className(),
'cors' => [
'Origin' => ['*'],
'Access-Control-Allow-Origin' => ['*'],
'Access-Control-Request-Method' => ['*'],
'Access-Control-Request-Headers' => ['*'],
'Access-Control-Allow-Credentials' => true,
'Access-Control-Max-Age' => 86400,
]
];
// 设置认证的方式
$behaviors['authenticator'] = [
'class' => APIAuth::className(),
'except' => ['OPTIONS'],
];
// 设置权限验证方式
$behaviors['access'] = [
'class' => AccessControl::className(),
];
return $behaviors;
}
}
- 在
UserController中修改behaviors()填加
/**
*
* 使用jwt token 验证,并设置login signup不需要验证
*/
public function behaviors()
{
$behaviors = ArrayHelper::merge(
parent::behaviors(), [
'authenticator' => [
'optional' => ['login','signup']
],
]
);
return $behaviors;
}
- 第一步使用
用户名/密码获取token
public function actionLogin()
{
$model = new LoginForm();
$model->setAttributes(Yii::$app->request->post());
try {
if ($user = $model->login()) {
return $user->access_token
}
} catch(yii\web\HttpException){
throw new yii\web\HttpException;
}
}
- 第二步所有请求头部携带token
Authorization:Bearer <your access-token>
- 使用权限
- 使用
admin/route的url 即可到后台管理,原理请参照yii的官方文档的RBAC - 如果需要将在下个版本提供所有页面的rest版
- 现在提供的接口
<?php
// 命名空间注意修改
namespace xxxx\controllers;
use Yii;
use yii\helpers\ArrayHelper;
use yii\web\NotFoundHttpException;
use clement\rest\components\Helper;
use clement\rest\components\MenuHelper;
use yii\web\User; // 注意不要使用其他的
use \base\BaseController;
class UserInfoController extends BaseController
{
public $modelClass = 'xxxx\User'; // 上面修改的User,即认证的User类
protected function verbs()
{
return ArrayHelper::merge(
parent::verbs(),
[
//关于options的严谨方法,需对options 处理
'info' => ['GET','OPTIONS'],
]
);
}
public function actionInfo(){
$request = \Yii::$app->request;
if($request->getIsOptions()){
return $this->ResponseOptions( $this->verbs()['info']);
}
$user = Yii::$app->getUser();
$userId = $user instanceof User ? $user->getId() : $user;
$res['userInfo']['menus'] = MenuHelper::getAssignedMenu($userId);
$res['userInfo']['resources'] = Helper::getPermissionByUser($userId);
return $res;
}
}
- 结果样例
{
-"menu": [
-{
"id": "1",
"name": "首页",
"route": "/teacher-default",
"parent_id": null
}
],
-"resources": [
-{
"url": "/admin/*",
"method": "",
"id": 1
}
]
}
clement/yii-rest-rbac 适用场景与选型建议
clement/yii-rest-rbac 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 39 次下载、GitHub Stars 达 5, 最近一次更新时间为 2018 年 03 月 25 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「admin」 「auth」 「yii」 「rbac」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 clement/yii-rest-rbac 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 clement/yii-rest-rbac 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 clement/yii-rest-rbac 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Laravel Multiauth package
2lenet/EasyAdminPlusBundle
Yii2 LightBox image galary widget uses Lightbox v2.10.0 by Lokesh Dhakar
A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.
Analysis module for finding problematical shop data.
This package provides a flexible way to add Role-based Permissions to Laravel 6.x
统计信息
- 总下载量: 39
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 6
- 点击次数: 0
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2018-03-25