flameart / restyii2
Yii 2 RESTful模板
这个包的官方仓库似乎已不存在,因此该包已被冻结。
Requires
- php: >=7.0.0
- ext-http: *
- codemix/yii2-excelexport: *
- firebase/php-jwt: *
- flameartlab/migration: *
- thamtech/yii2-ratelimiter-advanced: *
- yiisoft/yii2: ~2.0
- yiisoft/yii2-authclient: *
- yiisoft/yii2-swiftmailer: ~2.0 || ~2.1
Requires (Dev)
- codeception/base: ^2.4
- codeception/verify: ~1.0
- yiisoft/yii2-debug: ~2.1
- yiisoft/yii2-faker: ~2.0
- yiisoft/yii2-gii: ~2.1
This package is auto-updated.
Last update: 2023-12-26 19:03:49 UTC
README
用于SPA应用和移动端的快速后端原型启动器。所有现代应用的主要功能都已安装和配置。
功能
- 基于JSON的CRUD请求,类似于GraphQL,具有无限关系的深度
- 通过Gii在一键中为数据库中的所有表生成模型和REST控制器
- 生成Typescript ORM导入
- 性能优化
- 注册和认证
- Google、Facebook和其他第三方oauth-client已准备好
- 默认情况下具有角色系统,正确处理访客
- 每个用户角色的表中的每个字段的自定义访问规则
- 速率限制器:针对特定控制器,防止暴力破解、抓取和DDoS,默认情况下仅安装auth模块(但最好使用nginx)
- 通过Materialized Path范式完全支持树
- 自动迁移:包含FlameArt高级迁移生成工具,可以自动生成表和数据迁移
入门
安装步骤
-
安装到文件夹projectName
composer create-project --prefer-dist --remove-vcs --stability=dev flameart/restyii2 projectName cd projectName php init --env=Development --overwrite=All
对于生产环境发布,只需将环境替换为
--env=Production
,并使用composer update
而不是composer create-project
-
在
/common/config/main-local.php
中配置您的数据库设置 -
初始化迁移
php yii migrate --interactive=0 php yii migrate --migrationPath=@yii/rbac/migrations --interactive=0 php yii install/init
现在系统正在运行。您可以为其设置域名并检查:http://yourdomain/site/index
自动创建REST
- 在数据库中创建您的表
- 打开http://yourdomain/gii/restgen(仅在开发模式下工作)
- 选择表,点击预览,然后生成
- 或者您可以运行
yii gii/restgen --tableName=* --interactive=0 --overwrite=1
- 它将创建所有模型和控制器
- 或者您可以运行
- 系统自动创建
/rest/controllers/api/
中的控制器/common/models/DB/
中的表的可配置模型,它扩展了经典ActiveRecord模型/common/models/DB/models
中的经典ActiveRecord模型。无需更改此内容,在更改列或关系后,它将重新构建。请只使用可配置的模型
- 完成!检查您的REST http://yourdomain/api/v1/TABLENAME/index - 用于选择前20行
与REST一起工作
我有一个带有预定义方法的javascript模块:https://github.com/FlameArt/rest,或者您可以手动使用以下方法组合JSON请求
从数据库获取数据
- 端点:http://yourdomain/api/v1/TABLENAME/index
- POST/GET
- 格式:JSON
通常使用,获取2个指定的列,按用户名排序并分页:POST http://yourdomain/api/v1/user/index
{
fields: ["username", "phone"],
where: {"status": 'ACTIVE'},
sort: "username",
page: 1
}
- 如果未设置
fields
- 显示所有字段,当前用户可访问 - 如果未设置
where
或sort
- 无筛选或排序 - 如果未设置
page
或per-page
- 默认为第1页,每页20行
带评论的全功能请求
{
... Your select fields. Field "user" here have a Foreign key, so you just write all fields what you need from related table:
fields: {"id":"", "title":"", "user":
{
"name": "",
"phone": "",
... you can do infinity deep if columns have foreign keys, also here an array format with just field list ...
"country": ["code", "shortname"]
}
},
where: {
... WHERE status=5
"status": 5,
... Yii2 format for custom conditions, example:
"searchText": {"LIKE", "title", "some text"},
... FullText search (match - against):
"searchByFulltextIndex": {"FULLTEXT", "column", "some text"},
... and you can combine multiply AND & OR, details Yii2 format: https://yiiframework.cn/doc/guide/2.0/en/db-query-builder#where
},
}
在MySQL JSON字段中查找
应用程序支持使用 JSON_CONTAINS
(等价于OR)在SQL中搜索JSON字段(MySQL 5.7+)
{
where: [
json_field: [1,3,5]
]
}
删除项目
ACCESS_RULES
可以使用以下值作为 delete
规则
*
- 无规则,任何用户都可以删除任何行self
- 用户可以删除自己的行(比较当前表中的$USER_ATTRIBUTE
和用户ID)function($model, $data)
- 您可以配置您自己的删除行访问检查null
或delete
部分不存在 - 用户不能删除行
树
通过快速物化路径实现。它通过1个查询组合所有树。但您可以使用嵌套树或其他范式。
创建迁移 php yii migrate/create addTreeColumns
如此(items
- 您的表)
$this->addColumn('items', 'm_tree', $this->integer()->defaultValue(null));
$this->addColumn('items', 'm_path', $this->string(500)->defaultValue(null));
$this->addColumn('items', 'm_depth', $this->integer()->defaultValue(null));
$this->addColumn('items', 'm_sort', $this->integer()->defaultValue(null));
$this->createIndex('path', 'items', ['path']);
然后迁移 php yii migrate
。
现在,您可以在 Create
或 Edit
请求中添加以下参数
appendTo=0
用于新树或根项appendTo=123
将新或编辑的项添加到其他项,其主键为123,作为最后一个元素insertAfter=123
将具有此主键的节点移动到其他节点的位置之后insertFirst=123
将节点移动为父节点(主键为123)的第一个元素
删除请求默认删除 元素及其所有子元素。为保存子元素以任何目的
withoutChildrens
用于删除无子元素的节点(它们将移动到被删除节点的父节点)
读取树
为了填充树,只需将请求中的 tree
参数添加到根节点的主键,如下所示
{
"tree": 123
"where": {"status":1},
}
示例中的 123
是节点的主键(id
),您需要获取所有子节点。如您所见,您可以使用所有其他参数,如where、fields等。响应具有额外的字段 m_parent
,对于每个列都具有父节点的主键
填充当前用户的所有树
{"tree":0}
Gii 自动生成器
自动生成表模型和 TypeScript 导入
-
通过 Web 接口
- 访问 http://yourdomain/gii/restgen
- 选择多个表
- 预览和生成
-
通过命令行更新所有表
yii gii/restgen --tableName=* --interactive=0 --overwrite=1
在 rest/TSImports/
中的 TypeScript ORM 模型
数据访问安全
与为每个请求手动设置实体不同,此模板为每个用户设置表限制,包括他们可以查看和修改的字段,同时还使用经典的RBAC方案来描述更广泛的访问级别。这允许只继续开发前端,并从中请求所需的字段,而系统只会检查访问这些字段的权限。这允许只需设置一次后端,这正是其原始构思,同时保持安全性。
Self
字段参数:它将模型中的$USER_ATTRIBUTE
与当前用户ID进行比较。数据库中用户ID的默认字段名配置为user
,因此如果您使用其他字段名,请更改模型中的$USER_ATTRIBUTE
。例如,User
模型通过id
进行检查(用户只能查看或编辑自己的设置)
注册和认证
社交
注意:通过社交平台的注册和认证仅在实际域名上工作
您需要在/rest/config/main.php
的requests
中填写hostInfo
->您的网站域名
此外,您需要在服务中注册您的应用程序并获取Client ID
和Secret key
,然后将其写入/rest/config/main.php
-> authClientCollection
获取这些密钥的简单说明
- Facebook
- 访问https://developers.facebook.com/apps/
- 创建应用,类型:通过FB登录
- 填写redirect_uri:https://YOURDOMAIN/auth/social?authclient=facebook
- 对于
public_profile
和email
字段,获取高级访问权限(在权限选项卡中) - 在数据使用检查中确认协议
- Google
- 访问https://console.cloud.google.com/apis/credentials
- 创建项目
- 创建凭据 => OAuth客户端ID
- 填写redirect_uri:https://YOURDOMAIN/auth/social?authclient=google
电子邮件
首先,您需要配置电子邮件的smtp账户,原因:smtp邮件发送比原生客户端更安全、更可信的选项,原生客户端会将邮件直接发送到垃圾邮件文件夹,其次:您可以在函数列表中禁用不安全的proc_open。出于安全原因,像Gmail这样的服务使用临时应用程序密码,您可以在以下位置创建它:https://myaccount.google.com/u/1/apppasswords
然后配置/common/config/main.php
-> mailer
组件,只需写入完整的电子邮件地址(myname@gmail.com)和应用程序密码
电子邮件设计
所有电子邮件模板都放置在/common/mails/
,默认情况下,在注册和验证后发送Welcome
模板(对于通过社交平台注册的验证不需要)
文件上传
自动创建上传。它将文件保存到存储路径,并将所有路径保存在数据库中的字段中,使用;
分隔符。如果需要,删除旧文件 - 替换为新文件后、保存到数据库有问题后以及删除行后。
需要客户端请求(编辑或创建)
"myFilesField": [
{
"name": "trollface.jpg",
"data": "base64 encoded image"
},
{
"name": "file.zip",
"data": "base64 encoded file"
},
]
您需要类似此规则部分的image
或file
验证器规则
[['avatar'], 'image', 'extensions' => ['png', 'gif', 'jpg', ], 'maxSize' => 1024*1024, 'maxFiles' => 1]
UploadBehavior
- 默认为每个模型启用,它会在rules
中找到带有image
或file
验证器的字段。验证器中的每个字段都用于自动上传和保存到数据库。您可以在fieldsFolders
参数中为每个字段指定自己的文件夹,如下所示
[
'class' => UploadBehavior::class,
'fieldsFolders' => [
'avatar' => '/usersdata/avatar/',
'uploads' => '/usersdata/uploads/'
]
]
版本控制
您可以在 GlobalRestConfig
中添加版本,Rest Generator 将为每个版本创建独立的控制器。现有的控制器不会被覆盖。
Nginx 配置
您需要在同一 URI 下 yourdomain/usersdata
的配置中添加 /usersdata/
位置。它包含用户上传的文件、上传的默认头像。
推送通知
苹果
- 前往苹果开发者中心 -> 证书、标识符和配置文件 -> 证书 -> + -> 苹果推送通知服务 SSL(沙盒和正式环境)
- 创建 CSR 密钥
openssl req -new -newkey rsa:2048 -nodes -keyout yourname.key -out yourname.csr
- 上传到苹果,下载
.cer
证书 - 制作 PEM 文件
openssl x509 -in your_certificate.cer -inform der -out your_certificate.pem
谷歌(Android)
- 前往 Firebase https://console.firebase.google.com/ 并创建一个项目
- 项目概览 -> 项目设置 -> 云消息
- 项目凭证 -> 服务器密钥
常见问题解答
为什么使用基于 Cookie 的会话而不是 JWT 令牌?
安全原因
- 如果 SPA 应用将令牌存储在 localStorage 中,则绝对不安全
- 如果我们使用 SameSite HttpOnly 将 JWT 令牌设置为 Cookie,JWT 秘密密钥的泄露将允许伪造任何用户的任何请求。需要额外的检查:令牌已被发送的事实。
因此,令牌和会话之间没有区别:无论如何,我们都需要通过数据库检查它。
无论如何,JWT 验证已包含在模板中,您可以使用它