virginent / yii2-oauth2-rest-template
Yii2 Rest API 模板,包含 OAuth2(完全配置的 filsh/yii2-oauth2-server 扩展)
Requires
- php: >=5.4.0
- filsh/yii2-oauth2-server: 2.0.0
- yiisoft/yii2: 2.0.40
This package is auto-updated.
Last update: 2024-09-22 01:01:30 UTC
README
这是一个使用 OAuth2 服务器(使用 https://github.com/Filsh/yii2-oauth2-server)配置的 Yii2 Rest App 模板。解决了 OAuth2 服务器扩展的适配问题,根据 官方指南 建议构建了带有版本的目录结构,添加了一些现成的功能以加快开发。
您可以使用此模板作为创建服务 API 端的起点。
在 Docker 上运行
为了快速测试代码,我创建了此 https://github.com/ikaras/yii2-oauth2-rest-docker - 它使用 Docker Compose 启动带有所有必要配置和准备好请求的 LEMP 栈。只需遵循其中的说明即可。
安装
通过 Composer 安装
如果您没有 Composer,您可以通过访问 getcomposer.org 上的说明 来安装它。
然后,您可以使用以下命令安装应用程序
composer global require "fxp/composer-asset-plugin:~1.1.1"
composer create-project --stability="dev" --prefer-source ikaras/yii2-oauth2-rest-template .
配置
- 配置您的 Web 服务器(例如 Nginx 或 Apache)(见 这里),以查看
application/api/www目录。我在测试中使用域名api.loc。 - 在
application/api/config/common.php中更改连接到您的数据库 - 运行迁移
php application/api/yiic migrate --migrationPath=@yii/rbac/migrations --interactive=0 \
php application/api/yiic migrate --migrationPath=@vendor/filsh/yii2-oauth2-server/migrations --interactive=0 \
php application/api/yiic migrate --interactive=0 \
php application/api/yiic migrate --interactive=0 \
结构
\application # root folder for environment (frontend, backend, api, etc.)
\api # here is code for build REST API with OAuth2 server
| \common # common controllers and models for versions
| | \controllers # for tests created only one ProductController
| | \models # and one model Product
| \components # global for API components (parents for project's controllers, models, filters)
| |-APIModule.php # parent for all module/versions
| |-ActiveController.php # child of yii's rest ActiveController, parent for all ones in project
| |-Controller.php # child of yii's rest Controller
| | \db # contain parents for all project's ActiveRecord and ActiveQuery
| | \filters
| | | -OAuth2AccessFilter.php # MAIN IMPROVEMENT: analyze action publicity and scopes to attach filter
| | | # to authorize by access token
| | \traits # contain ControllersCommonTrait.php with configuration of filters, used in both rest controllers
| \config
| \migrations # contain migrations for create users table, filling demo products and scopes
| \models # have User model
| \versions # directory for versions, each version is module as recommend in official yii2 guide
| | \v1 # created for test 1st version with childs of ProductController and Product model
| \www # public directory, containt index.php
测试
条件
- 域名:
api.loc(如果您不想使用虚拟主机,也可以使用类似https:///TestOAuth2/application/api/www/index.php/的内容) - 版本:
v1 - API 点:
/products、/products/<id>、/products/custom、/products/protected - 用户: 登录:
admin@api.loc,密码:123123123 - 作用域: 默认(默认作用域,CO :))、自定义、受保护 - 用于访问 /products/custom 和 /products/protected 点
描述
为了测试,创建了 active rest controller ProductController 用于管理 Product 模型。
此控制器具有以下访问规则(以 yii2 格式)
public function accessRules()
{
return [
['allow' => true, 'roles' => ['?']],
[
'allow' => true,
'actions' => ['view','create','update','delete'],
'roles' => ['@'],
],
[
'allow' => true,
'actions' => ['custom'],
'roles' => ['@'],
'scopes' => ['custom'],
],
[
'allow' => true,
'actions' => ['protected'],
'roles' => ['@'],
'scopes' => ['protected'],
]
];
}
api 中的每个控制器都可以覆盖方法 accessRules 以为其自身提供访问规则。规则可以包含额外的属性 - scope,这意味着访问令牌应该具有额外的权限。
因此,从规则中我们可以理解到
- 控制器中的所有操作都是开放的(请求可以不包含访问令牌),但是
- 操作
view、create、update、delete- 仅限授权用户可用 - 并且对操作
custom和protected需要额外的作用域
测试请求
1. 请求到公开 API 点
curl -i -H "Accept:application/json" -H "Content-Type:application/json" "http://api.loc/v1/products"
2. 请求获取访问令牌
curl -i -H "Accept:application/json" -H "Content-Type:application/json" "http://api.loc/oauth2/token" -XPOST \
-d '{"grant_type":"password","username":"admin@api.loc","password":"123123123","client_id":"testclient","client_secret":"testpass"}'
3. 请求获取带有作用域的访问令牌
curl -i -H "Accept:application/json" -H "Content-Type:application/json" "http://api.loc/oauth2/token" -XPOST \
-d '{"grant_type":"password","username":"admin@api.loc","password":"123123123","client_id":"testclient","client_secret":"testpass","scope":"custom"}'
4. 请求受保护的 API 点
curl -i -H "Accept:application/json" -H "Content-Type:application/json" \
"http://api.loc/v1/products/1?access_token=76f4c0d40347f24a73799335cefb495be9ea364b"
都做了什么?
- 获取了 Yii2 框架并创建了通用的目录结构(见 结构 部分)。
- 使用 官方手册 配置 Yii2 为 RESTful Web 服务。
- 为项目中的所有组件创建了继承的父类(保存于
components目录)。更多信息 - 请参阅结构部分。类Controller和ActiveController是所有使用相同特质的控制器之父类。 ControllersCommonTrait - 它将所有必要的过滤器连接(重定义)到控制器动作。 - 目录
common由每个版本的公共控制器和模型组成。 - 然后我附加并配置了Filsh的Yii2 OAuth2扩展,其扩展基于广泛使用的PHP OAuth2服务器库。所有详细信息都可以在这些仓库中找到。以下是我配置的内容:
- 在common配置中配置模块
oauth2; - 使用
oauth2模块采用方法User::findIdentityByAccessToken通过令牌授权用户。
- 开发了OAuth2AccessFilter并替换了标准的Yii2 AccessFilter(在ControllersCommonTrait中,所有控制器)以更方便地使用Scopes。关于这一点,请向下阅读。
Scopes
如官方OAuth2库文档所述
OAuth2应用程序中Scopes的使用通常对于适当的权限管理至关重要。Scope用于限制资源所有者授予客户端的授权。最常见的使用是Facebook允许用户授权客户端执行各种不同的功能(“访问基本信息”,“在墙上发布”等)。
因此,每个令牌都可以运行相应的API点时具有特定的权限。在我们的案例中,API点是动作。
在Yii2中,我们已经有工具可以控制用户角色对特定动作的访问,所以我决定扩展其功能以定义动作的Scopes。
因此,创建了OAuth2AccessFilter,它复制(不是继承,结构不允许继承)标准AccessFilter逻辑以与规则一起工作,并具有额外的逻辑来处理通过oauth2模块处理私动作的Scopes。
因此,如果用户的角色允许他运行动作(API点),则将检查用户的令牌是否有执行此操作所需的Scopes(如果动作已定义有限的Scopes)。使用示例可以在ProductController中找到,这意味着只有具有包含custom Scopes的令牌的授权用户才能访问custom动作。