virginent/yii2-oauth2-rest-template

Yii2 Rest API 模板,包含 OAuth2(完全配置的 filsh/yii2-oauth2-server 扩展)

dev-master 2021-01-21 16:27 UTC

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 .

配置

  1. 配置您的 Web 服务器(例如 Nginx 或 Apache)(见 这里),以查看 application/api/www 目录。我在测试中使用域名 api.loc
  2. application/api/config/common.php 中更改连接到您的数据库
  3. 运行迁移
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,这意味着访问令牌应该具有额外的权限。

因此,从规则中我们可以理解到

  • 控制器中的所有操作都是开放的(请求可以不包含访问令牌),但是
  • 操作 viewcreateupdatedelete - 仅限授权用户可用
  • 并且对操作 customprotected 需要额外的作用域

测试请求

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"

都做了什么?

  1. 获取了 Yii2 框架并创建了通用的目录结构(见 结构 部分)。
  2. 使用 官方手册 配置 Yii2 为 RESTful Web 服务。
  3. 为项目中的所有组件创建了继承的父类(保存于components目录)。更多信息 - 请参阅结构部分。类ControllerActiveController是所有使用相同特质的控制器之父类。 ControllersCommonTrait - 它将所有必要的过滤器连接(重定义)到控制器动作。
  4. 目录common由每个版本的公共控制器和模型组成。
  5. 然后我附加并配置了Filsh的Yii2 OAuth2扩展,其扩展基于广泛使用的PHP OAuth2服务器库。所有详细信息都可以在这些仓库中找到。以下是我配置的内容:
  1. 开发了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动作。