ikaras/yii2-oauth2-rest-template

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

dev-master 2016-02-19 09:59 UTC

This package is not auto-updated.

Last update: 2024-09-25 15:42:00 UTC


README

这是一个配置了 OAuth2 服务器的 Yii2 Rest 应用模板(使用 https://github.com/Filsh/yii2-oauth2-server)。解决了 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应用程序中使用Scope对于适当的权限控制通常是关键的。Scope用于限制资源所有者授予客户端的授权。最常见的用途是Facebook允许用户授权客户端执行各种不同的功能(“访问基本信息”,“在墙上发布”等)。

因此,每个令牌都可以有特定的权限来运行相应的API点。在我们的案例中,API点是动作。

在Yii2中,我们已经有了一个工具可以根据用户角色控制特定动作的访问,所以我决定扩展其功能以定义动作的Scopes。

因此,创建了OAuth2AccessFilter,它复制(不是继承,结构不允许继承)了标准AccessFilter的逻辑,并使用额外的逻辑处理由oauth2模块处理的私有动作的Scopes。

因此,如果用户的角色允许他运行动作(API点),则将检查用户的令牌是否具有执行该动作所需的Scopes(如果动作已定义有限的Scopes)。使用示例可以在ProductController中找到,这意味着只有授权的用户,其令牌包含custom范围,才能访问custom动作。