flameart/restyii2

Yii 2 RESTful模板

这个包的官方仓库似乎已不存在,因此该包已被冻结。

v1.0.0 2022-04-27 20:36 UTC

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高级迁移生成工具,可以自动生成表和数据迁移

入门

安装步骤

  1. 安装到文件夹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

  2. /common/config/main-local.php中配置您的数据库设置

  3. 初始化迁移

     php yii migrate --interactive=0
     php yii migrate --migrationPath=@yii/rbac/migrations --interactive=0
     php yii install/init
    

现在系统正在运行。您可以为其设置域名并检查:http://yourdomain/site/index

自动创建REST

  1. 在数据库中创建您的表
  2. 打开http://yourdomain/gii/restgen(仅在开发模式下工作)
  3. 选择表,点击预览,然后生成
    • 或者您可以运行yii gii/restgen --tableName=* --interactive=0 --overwrite=1 - 它将创建所有模型和控制器
  4. 系统自动创建
    1. /rest/controllers/api/中的控制器
    2. /common/models/DB/中的表的可配置模型,它扩展了经典ActiveRecord模型
    3. /common/models/DB/models中的经典ActiveRecord模型。无需更改此内容,在更改列或关系后,它将重新构建。请只使用可配置的模型
  5. 完成!检查您的REST http://yourdomain/api/v1/TABLENAME/index - 用于选择前20行

与REST一起工作

我有一个带有预定义方法的javascript模块:https://github.com/FlameArt/rest,或者您可以手动使用以下方法组合JSON请求

从数据库获取数据

通常使用,获取2个指定的列,按用户名排序并分页:POST http://yourdomain/api/v1/user/index

{
    fields: ["username", "phone"],
    where: {"status": 'ACTIVE'},
    sort: "username",
    page: 1
}
  • 如果未设置 fields - 显示所有字段,当前用户可访问
  • 如果未设置 wheresort - 无筛选或排序
  • 如果未设置 pageper-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) - 您可以配置您自己的删除行访问检查
  • nulldelete 部分不存在 - 用户不能删除行

通过快速物化路径实现。它通过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

现在,您可以在 CreateEdit 请求中添加以下参数

  • 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 接口

  • 通过命令行更新所有表

    • 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.phprequests中填写hostInfo ->您的网站域名

此外,您需要在服务中注册您的应用程序并获取Client IDSecret key,然后将其写入/rest/config/main.php -> authClientCollection

获取这些密钥的简单说明

电子邮件

首先,您需要配置电子邮件的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"
    },
]

您需要类似此规则部分的imagefile验证器规则

     [['avatar'], 'image', 'extensions' => ['png', 'gif', 'jpg', ], 'maxSize' => 1024*1024, 'maxFiles' => 1]

UploadBehavior - 默认为每个模型启用,它会在rules中找到带有imagefile验证器的字段。验证器中的每个字段都用于自动上传和保存到数据库。您可以在fieldsFolders参数中为每个字段指定自己的文件夹,如下所示

   [
         'class' => UploadBehavior::class,
         'fieldsFolders' => [
            'avatar' => '/usersdata/avatar/',
            'uploads' => '/usersdata/uploads/'
         ]
   ]

版本控制

您可以在 GlobalRestConfig 中添加版本,Rest Generator 将为每个版本创建独立的控制器。现有的控制器不会被覆盖。

Nginx 配置

您需要在同一 URI 下 yourdomain/usersdata 的配置中添加 /usersdata/ 位置。它包含用户上传的文件、上传的默认头像。

推送通知

苹果

  1. 前往苹果开发者中心 -> 证书、标识符和配置文件 -> 证书 -> + -> 苹果推送通知服务 SSL(沙盒和正式环境)
  2. 创建 CSR 密钥 openssl req -new -newkey rsa:2048 -nodes -keyout yourname.key -out yourname.csr
  3. 上传到苹果,下载 .cer 证书
  4. 制作 PEM 文件 openssl x509 -in your_certificate.cer -inform der -out your_certificate.pem

谷歌(Android)

  1. 前往 Firebase https://console.firebase.google.com/ 并创建一个项目
  2. 项目概览 -> 项目设置 -> 云消息
  3. 项目凭证 -> 服务器密钥

常见问题解答

为什么使用基于 Cookie 的会话而不是 JWT 令牌?

安全原因

  • 如果 SPA 应用将令牌存储在 localStorage 中,则绝对不安全
  • 如果我们使用 SameSite HttpOnly 将 JWT 令牌设置为 Cookie,JWT 秘密密钥的泄露将允许伪造任何用户的任何请求。需要额外的检查:令牌已被发送的事实。

因此,令牌和会话之间没有区别:无论如何,我们都需要通过数据库检查它。

无论如何,JWT 验证已包含在模板中,您可以使用它