单文件 PHP 脚本,将 REST API 添加到 MySQL/MariaDB、PostgreSQL、SQL Server 或 SQLite 数据库。
操作方法:将“ api.php
”上传到您的网络服务器,将其配置为连接到您的数据库,拥有即时的全功能 REST API。
注意:这是 PHP 中的 TreeQL 参考实现。
PHP 7.2 或更高版本,并为以下数据库系统之一启用了 PDO 驱动程序:
MySQL 5.7 / MariaDB 10.0 或更高版本,用于 MySQL 中的空间功能
PostgreSQL 9.5 或更高版本,带有用于空间特征的 PostGIS 2.2 或更高版本
SQL Server 2017 或更高版本(2019 还支持 Linux)
SQLite 3.16 或更高版本(不支持空间功能)
从最新版本下载“ api.php
”文件:
https://github.com/mevdschee/php-crud-api/releases/latest 或直接来自:
https://raw.githubusercontent.com/mevdschee/php-crud-api/main/api.php
这是一个单文件应用程序!将“ api.php
”上传到某个地方并享受吧!
对于本地开发,您可以运行 PHP 的内置 Web 服务器:
php -S localhost:8080
通过打开以下 URL 来测试脚本:
http://localhost:8080/api.php/records/posts/1
不要忘记修改文件底部的配置。
或者,您可以将此项目集成到您选择的 Web 框架中,请参阅:
Laravel 的自动 REST API
Symfony 4 的自动 REST API
SlimPHP 4 的自动 REST API
在这些集成中,Composer 用于将此项目作为依赖项加载。
对于不使用 Composer 的人,提供了文件“ api.include.php
”。该文件包含“ api.php
”中的所有内容(除了“ src/index.php
”中的配置),并且可以由 PHP 的“include”函数使用。
在文件“ api.php
”的底部编辑以下行:
$config = new Config([ 'username' => 'xxx', 'password' => 'xxx', 'database' => 'xxx', ]);
这些是所有配置选项及其括号之间的默认值:
“驱动程序”: mysql
、 pgsql
、 sqlsrv
或sqlite
( mysql
)
“address”:数据库服务器的主机名(或文件名)( localhost
)
“port”:数据库服务器的TCP端口(默认为驱动程序默认端口)
“username”:连接数据库的用户的用户名(无默认)
“password”:连接数据库的用户密码(无默认)
“database”:连接的数据库(无默认值)
“command”:用于初始化数据库连接的额外 SQL(无)
“tables”:以逗号分隔的要发布的表列表(默认为“all”)
“mapping”:逗号分隔的表/列映射列表(无映射)
“geometrySrid”:从 WKT 转换为几何时假定的 SRID ( 4326
)
“middlewares”:要加载的中间件列表( cors
)
“controllers”:要加载的控制器列表( records,geojson,openapi,status
)
“customControllers”:要加载的用户自定义控制器列表(无默认值)
"openApiBase": OpenAPI 信息 ( {"info":{"title":"PHP-CRUD-API","version":"1.0.0"}}
)
“cacheType”: TempFile
、 Redis
、 Memcache
、 Memcached
或NoCache
( TempFile
)
“cachePath”:缓存的路径/地址(默认为系统的临时目录)
“cacheTime”:缓存有效的秒数( 10
)
“jsonOptions”:用于编码 JSON 的选项 ( JSON_UNESCAPED_UNICODE
)
“debug”:在“X-Exception”标头中显示错误 ( false
)
“basePath”:API 的 URI 基本路径(默认使用 PATH_INFO 确定)
所有配置选项也可用作环境变量。使用大写字母、“PHP_CRUD_API_”前缀和下划线来编写断词的配置选项,例如:
PHP_CRUD_API_DRIVER=mysql
PHP_CRUD_API_ADDRESS=本地主机
PHP_CRUD_API_PORT=3306
PHP_CRUD_API_DATABASE=php-crud-api
PHP_CRUD_API_USERNAME=php-crud-api
PHP_CRUD_API_PASSWORD=php-crud-api
PHP_CRUD_API_DEBUG=1
环境变量优先于 PHP 配置。
这些限制和约束适用:
主键应该是自动递增(从 1 到 2^53)或 UUID
不支持复合主键和复合外键
不支持复杂的写入(事务)
不支持复杂查询调用函数(如“concat”或“sum”)
数据库必须支持并定义外键约束
SQLite 不能有 bigint 类型的自动递增主键
SQLite 不支持更改表列(结构)
支持以下功能:
Composer 安装或单个 PHP 文件,易于部署。
代码量极少,易于适配和维护
支持 POST 变量作为输入 (x-www-form-urlencoded)
支持 JSON 对象作为输入
支持JSON数组作为输入(批量插入)
使用类型规则和回调清理和验证输入
数据库、表、列、记录的权限系统
支持多租户单数据库和多数据库布局
多域CORS支持跨域请求
支持从多个表读取连接结果
支持多种条件搜索
分页、排序、前 N 列表和列选择
使用嵌套结果进行关系检测(belongsTo、hasMany 和 HABTM)
通过 PATCH 的原子增量支持(对于计数器)
支持 Base64 编码的二进制字段
WKT 和 GeoJSON 支持的空间/GIS 字段和过滤器
映射表和列名称以支持遗留系统
使用 OpenAPI 工具生成 API 文档
通过 API 密钥、JWT 令牌或用户名/密码进行身份验证
数据库连接参数可能取决于身份验证
支持读取 JSON 格式的数据库结构
支持使用 REST 端点修改数据库结构
包含安全增强中间件
符合标准:PSR-4、PSR-7、PSR-12、PSR-15 和 PSR-17
相关项目:
PHP-CRUD-API 快速入门:一个可定制、随时可用的 docker compose 文件,具有 PHP-CRUD-API。
PHP-CRUD-API 过滤器生成器:一个从表达式创建 PHP-CRUD-API 过滤器的 JavaScript 库。
JS-CRUD-API:PHP-CRUD-API API 的 JavaScript 客户端库
PHP-API-AUTH:单文件 PHP 脚本,是 PHP-CRUD-API 的身份验证提供程序
PHP-CRUD-UI:将 UI 添加到 PHP-CRUD-API 项目的单文件 PHP 脚本。
PHP-CRUD-ADMIN:单文件 PHP 脚本,将数据库管理界面添加到 PHP-CRUD-API 项目。
PHP-SP-API:将 REST API 添加到 SQL 数据库的单文件 PHP 脚本。
dexie-mysql-sync:本地IndexedDB和MySQL数据库之间的同步。
ra-data-treeql:NPM 包,为 React Admin 提供数据提供程序。
scriptPilot/vueuse:除了 VueUse.org(支持 PHP-CRUD-API)之外的 Vue 可组合项。
scriptPilot/add-php-backend:将 MySQL、phpMyAdmin 和 PHP-CRUD-API 添加到您的开发环境。
VUE-CRUD-UI:单文件 Vue.js 脚本,将 UI 添加到 PHP-CRUD-API 项目。
该脚本也有端口:
Go-CRUD-API(正在进行中)
Java JDBC 作者:Ivan Kolchagov (v1)
Java Spring Boot + jOOQ(v2:正在进行中)
该脚本还有一些概念验证端口,仅支持以下语言中的基本 REST CRUD 功能:PHP、Java、Go、C# .net core、Node.js 和 Python。
您可以使用以下命令安装该项目的所有依赖项:
php install.php
您可以使用以下命令将所有文件编译为单个“ api.php
”文件:
php build.php
请注意,当您将此项目集成到另一个项目或框架中时,您不使用编译(而是使用 Composer)。
您可以通过以下 URL 访问未编译的代码:
http://localhost:8080/src/records/posts/1
未编译的代码驻留在“ src
”和“ vendor
”目录中。 “ vendor
”目录包含依赖项。
您可以使用以下命令更新该项目的所有依赖项:
php update.php
该脚本将安装并运行 Composer 以更新依赖项。
注意:更新脚本将修补供应商目录中的依赖项以实现 PHP 7.0 兼容性。
TreeQL 允许您根据 SQL 数据库结构(关系)和查询创建 JSON 对象“树”。
它大致基于 REST 标准,并受到 json:api 的启发。
示例 posts 表只有几个字段:
posts ======= id title content created
下面的CRUD+List操作作用于这张表。
如果你想创建一条记录,请求可以写成 URL 格式:
POST /records/posts
您必须发送包含以下内容的正文:
{ "title": "Black is the new red", "content": "This is the second post.", "created": "2018-03-06T21:34:01Z" }
它将返回新创建记录的主键值:
2
要从此表中读取记录,可以将请求以 URL 格式编写为:
GET /records/posts/1
其中“1”是您要读取的记录的主键值。它将返回:
{ "id": 1 "title": "Hello world!", "content": "Welcome to the first post.", "created": "2018-03-05T20:12:56Z" }
在读取操作中,您可以应用连接。
要更新此表中的记录,可以将请求以 URL 格式编写为:
PUT /records/posts/1
其中“1”是您要更新的记录的主键值。作为正文发送:
{ "title": "Adjusted title!" }
这会调整帖子的标题。返回值是设置的行数:
1
如果你想从这个表中删除一条记录,请求可以写成 URL 格式:
DELETE /records/posts/1
它将返回已删除的行数:
1
要列出该表中的记录,可以将请求以 URL 格式编写为:
GET /records/posts
它将返回:
{ "records":[ { "id": 1, "title": "Hello world!", "content": "Welcome to the first post.", "created": "2018-03-05T20:12:56Z" } ] }
在列表操作中,您可以应用过滤器和连接。
过滤器使用“filter”参数在列表调用中提供搜索功能。您需要指定列名、逗号、匹配类型、另一个逗号以及要过滤的值。这些是支持的匹配类型:
“cs”:包含字符串(字符串包含值)
“sw”:以(字符串以值开头)开头
“ew”:以(字符串以值结尾)结尾
“eq”:等于(字符串或数字完全匹配)
“lt”:低于(数字低于值)
“le”:小于或等于(数字小于或等于值)
“ge”:大于或等于(数字大于或等于值)
“gt”:大于(数字大于值)
“bt”:之间(数字位于两个逗号分隔值之间)
“in”:in(数字或字符串位于逗号分隔的值列表中)
“is”:为空(字段包含“NULL”值)
您可以通过在前面添加“n”字符来否定所有过滤器,以便“eq”变为“neq”。过滤器使用示例如下:
GET /records/categories?filter=name,eq,Internet GET /records/categories?filter=name,sw,Inter GET /records/categories?filter=id,le,1 GET /records/categories?filter=id,ngt,1 GET /records/categories?filter=id,bt,0,1 GET /records/categories?filter=id,in,0,1
输出:
{ "records":[ { "id": 1 "name": "Internet" } ] }
在下一节中,我们将深入探讨如何在单个列表调用上应用多个过滤器。
可以通过在 URL 中重复“filter”参数来应用过滤器。例如以下网址:
GET /records/categories?filter=id,gt,1&filter=id,lt,3
将请求所有类别“其中 id > 1 且 id < 3”。如果你想要“where id = 2 or id = 4”你应该写:
GET /records/categories?filter1=id,eq,2&filter2=id,eq,4
正如您所看到的,我们在“filter”参数中添加了一个数字,以指示应应用“OR”而不是“AND”。请注意,您还可以重复“filter1”并在“OR”内创建“AND”。由于您还可以通过添加字母 (af) 更深入一层,因此您可以创建几乎任何相当复杂的条件树。
注意:您只能对请求的表(不能对其包含的表)进行过滤,并且过滤器仅应用于列表调用。
默认情况下,所有列均被选中。使用“include”参数,您可以选择特定的列。您可以使用点来分隔表名和列名。多列应以逗号分隔。星号(“*”)可以用作通配符来指示“所有列”。与“包含”类似,您可以使用“排除”参数来删除某些列:
GET /records/categories/1?include=name GET /records/categories/1?include=categories.name GET /records/categories/1?exclude=categories.id
输出:
{ "name": "Internet" }
注意:用于包含相关实体的列会自动添加,并且不能从输出中省略。
使用“order”参数您可以排序。默认情况下,排序按升序排列,但通过指定“desc”可以反转:
GET /records/categories?order=name,desc GET /records/categories?order=id,desc&order=name
输出:
{ "records":[ { "id": 3 "name": "Web development" }, { "id": 1 "name": "Internet" } ] }
注意:您可以使用多个“order”参数对多个字段进行排序。您不能对“连接”列进行排序。
“size”参数限制返回记录的数量。这可以与“order”参数一起用于前 N 个列表(使用降序)。
GET /records/categories?order=id,desc&size=1
输出:
{ "records":[ { "id": 3 "name": "Web development" } ] }
注意:如果您还想知道记录总数,您可能需要使用“page”参数。
“page”参数保存所请求的页面。默认页面大小为 20,但可以调整(例如调整为 50)。
GET /records/categories?order=id&page=1 GET /records/categories?order=id&page=1,50
输出:
{ "records":[ { "id": 1 "name": "Internet" }, { "id": 3 "name": "Web development" } ], "results": 2 }
元素“results”保存表中的记录总数,如果不使用分页,则将返回该记录总数。
注意:由于未排序的页面无法分页,因此页面将按主键排序。
假设您有一个包含评论(由用户发表)的帖子表,并且帖子可以包含标签。
posts comments users post_tags tags ======= ======== ======= ========= ======= id id id id id title post_id username post_id name content user_id phone tag_id created message
当您想列出带有评论用户和标签的帖子时,您可以要求两个“树”路径:
posts -> comments -> users posts -> post_tags -> tags
这些路径具有相同的根,并且该请求可以以 URL 格式编写为:
GET /records/posts?join=comments,users&join=tags
在这里,您可以省略将帖子绑定到标签的中间表。在此示例中,您会看到所有三种表关系类型(hasMany、belongsTo 和 hasAndBelongsToMany)均已生效:
“帖子”有很多“评论”
“评论”属于“用户”
“帖子”拥有并属于许多“标签”
这可能会导致以下 JSON 数据:
{ "records":[ { "id": 1, "title": "Hello world!", "content": "Welcome to the first post.", "created": "2018-03-05T20:12:56Z", "comments": [ { id: 1, post_id: 1, user_id: { id: 1, username: "mevdschee", phone: null, }, message: "Hi!" }, { id: 2, post_id: 1, user_id: { id: 1, username: "mevdschee", phone: null, }, message: "Hi again!" } ], "tags": [] }, { "id": 2, "title": "Black is the new red", "content": "This is the second post.", "created": "2018-03-06T21:34:01Z", "comments": [], "tags": [ { id: 1, message: "Funny" }, { id: 2, message: "Informational" } ] } ] }
您会看到检测到“belongsTo”关系,并且外键值被引用的对象替换。如果是“hasMany”和“hasAndBelongsToMany”,则表名称将用作对象的新属性。
当您想要创建、读取、更新或删除时,您可以在 URL 中指定多个主键值。您还需要在请求正文中发送一个数组而不是对象来创建和更新。
要从此表中读取记录,可以将请求以 URL 格式编写为:
GET /records/posts/1,2
结果可能是:
[ { "id": 1, "title": "Hello world!", "content": "Welcome to the first post.", "created": "2018-03-05T20:12:56Z" }, { "id": 2, "title": "Black is the new red", "content": "This is the second post.", "created": "2018-03-06T21:34:01Z" } ]
同样,当你想要批量更新时,URL 格式的请求写为:
PUT /records/posts/1,2
其中“1”和“2”是要更新的记录的主键值。正文应包含与 URL 中主键相同数量的对象:
[ { "title": "Adjusted title for ID 1" }, { "title": "Adjusted title for ID 2" } ]
这会调整帖子的标题。返回值是设置的行数:
[1,1]
这意味着有两个更新操作,每个操作都设置了一行。批处理操作使用数据库事务,因此它们要么全部成功,要么全部失败(成功的会回滚)。如果失败,主体将包含错误文档列表。在以下响应中,第一个操作成功,但批次的第二个操作由于完整性冲突而失败:
[ { "code": 0, "message": "Success" }, { "code": 1010, "message": "Data integrity violation" } ]
如果其中一个批处理操作失败,响应状态代码将始终为 424(失败的依赖项)。
要将多条记录插入到该表中,可以将请求以 URL 格式编写为:
POST /records/posts
正文应包含要插入的记录数组:
[ { "title": "Hello world!", "content": "Welcome to the first post.", "created": "2018-03-05T20:12:56Z" }, { "title": "Black is the new red", "content": "This is the second post.", "created": "2018-03-06T21:34:01Z" } ]
返回值也是一个包含新插入记录的主键的数组:
[1,2]
请注意,DELETE 的批处理操作遵循与 PUT 相同的模式,但没有主体。
对于空间支持,有一组额外的过滤器可以应用于几何列,并且以“s”开头:
“sco”:空间包含(几何包含另一个)
“scr”:空间交叉(几何交叉另一个)
“sdi”:空间不相交(几何形状与另一个不相交)
“seq”:空间相等(几何形状等于另一个)
“sin”:空间相交(几何与另一个相交)
“sov”:空间重叠(几何重叠另一个)
“sto”:空间接触(几何接触另一个)
“swi”:空间内部(几何图形在另一个几何图形内部)
“sic”:空间是封闭的(几何是封闭且简单的)
“sis”:空间简单(几何简单)
“siv”:空间有效(几何有效)
这些过滤器基于 OGC 标准,其中表示几何列的 WKT 规范也是如此。请注意,从 WKT 转换为几何时假定的 SRID 由配置变量geometrySrid
指定,默认为 4326 (WGS 84)。
GeoJSON 支持是 GeoJSON 格式的表和记录的只读视图。支持这些请求:
method path - operation - description ---------------------------------------------------------------------------------------- GET /geojson/{table} - list - lists records as a GeoJSON FeatureCollection GET /geojson/{table}/{id} - read - reads a record by primary key as a GeoJSON Feature
“ /geojson
”端点在内部使用“ /records
”端点并继承所有功能,例如连接和过滤器。它还支持“几何”参数来指示几何列的名称,以防表有多个几何列。对于地图视图,它支持“bbox”参数,您可以在其中指定左上角和右下角坐标(以逗号分隔)。 GeoJSON 实现支持以下几何类型:
观点
多点
线串
多行字符串
多边形
多重多边形
GeoJSON 功能默认启用,但可以使用“控制器”配置禁用。
为了支持为遗留系统(例如 Wordpress)(的一部分)创建 API,您可能需要映射表和列名称,因为如果不更改软件就无法改进它们,而名称可能需要进行一些改进以保持一致性。该配置允许您使用逗号分隔的映射列表重命名表和列,这些映射用等号分隔,如下所示:
'mapping' => 'wp_posts=posts,wp_posts.ID=posts.id',
此特定示例将在“ posts
”端点(而不是“ wp_posts
”)公开“ wp_posts
”表,并将该表中的“ ID
”列公开为“ id
”属性(小写而不是大写)。
注意:由于这两个映射重叠,因此可以省略第一个(不太具体)映射。
您可以使用“middlewares”配置参数启用以下中间件:
“防火墙”:限制对特定IP地址的访问
“sslRedirect”:强制通过 HTTPS 而不是 HTTP 进行连接
“cors”:支持 CORS 请求(默认启用)
“xsrf”:使用“双重提交 Cookie”方法阻止 XSRF 攻击
“ajaxOnly”:限制非AJAX请求以防止XSRF攻击
“apiKeyAuth”:支持“API密钥身份验证”
“apiKeyDbAuth”:支持“API密钥数据库身份验证”
“dbAuth”:支持“数据库身份验证”
“wpAuth”:支持“Wordpress 身份验证”
“jwtAuth”:支持“JWT 身份验证”
“basicAuth”:支持“基本身份验证”
“reconnect”:使用不同的参数重新连接数据库
“authorization”:限制对某些表或列的访问
“validation”:返回自定义规则和默认类型规则的输入验证错误
“ipAddress”:使用创建时的 IP 地址填充受保护字段
“sanitation”:在创建和更新时应用输入卫生
“multiTenancy”:限制多租户场景中的租户访问
“pageLimits”:限制列表操作以防止数据库抓取
“joinLimits”:限制连接参数以防止数据库抓取
“textSearch”:使用简单参数在所有文本字段中搜索
“customization”:提供请求和响应定制的处理程序
“json”:支持将 JSON 字符串读/写为 JSON 对象/数组
“xml”:将所有输入和输出从 JSON 转换为 XML
“middlewares”配置参数是启用的中间件的逗号分隔列表。您可以使用中间件特定的配置参数来调整中间件行为:
“firewall.reverseProxy”:使用反向代理时设置为“true”(“”)
“firewall.allowedIpAddresses”:允许连接的IP地址列表(“”)
“cors.allowedOrigins”:CORS 标头中允许的来源(“*”)
“cors.allowHeaders”:CORS 请求中允许的标头(“Content-Type、X-XSRF-TOKEN、X-Authorization”)
“cors.allowMethods”:CORS 请求中允许的方法(“OPTIONS、GET、PUT、POST、DELETE、PATCH”)
“cors.allowCredentials”:允许 CORS 请求中的凭据(“true”)
“cors.exposeHeaders”:允许浏览器访问的白名单标头(“”)
“cors.maxAge”:CORS 授予的有效时间(以秒为单位)(“1728000”)
"xsrf.excludeMethods": 不需要XSRF保护的方法("OPTIONS,GET")
“xsrf.cookieName”:XSRF 保护 cookie 的名称(“XSRF-TOKEN”)
“xsrf.headerName”:XSRF 保护标头的名称(“X-XSRF-TOKEN”)
“ajaxOnly.excludeMethods”:不需要AJAX的方法(“OPTIONS,GET”)
“ajaxOnly.headerName”:所需标头的名称(“X-Requested-With”)
“ajaxOnly.headerValue”:所需标头的值(“XMLHttpRequest”)
“apiKeyAuth.mode”:如果您想允许匿名访问,则设置为“可选”(“必需”)
“apiKeyAuth.header”:API 密钥标头的名称(“X-API-Key”)
“apiKeyAuth.keys”:有效的 API 密钥列表(“”)
“apiKeyDbAuth.mode”:如果您想允许匿名访问,则设置为“可选”(“必需”)
“apiKeyDbAuth.header”:API 密钥标头的名称(“X-API-Key”)
“apiKeyDbAuth.usersTable”:用于存储用户的表(“users”)
“apiKeyDbAuth.apiKeyColumn”:保存 API 密钥(“api_key”)的用户表列
“dbAuth.mode”:如果您想允许匿名访问,则设置为“可选”(“必需”)
“dbAuth.usersTable”:用于存储用户的表(“users”)
“dbAuth.loginTable”:用于检索登录用户信息(“users”)的表或视图
“dbAuth.usernameColumn”:保存用户名的用户表列(“username”)
“dbAuth.passwordColumn”:保存密码的用户表列(“password”)
“dbAuth.returnedColumns”:登录成功时返回的列,空表示“全部”(“”)
“dbAuth.usernameFormField”:保存用户名的表单字段的名称(“username”)
“dbAuth.passwordFormField”:保存密码的表单字段的名称(“password”)
“dbAuth.newPasswordFormField”:保存新密码的表单字段的名称(“newPassword”)
“dbAuth.registerUser”:JSON 用户数据(或“1”),以防您希望启用 /register 端点(“”)
"dbAuth.loginAfterRegistration":如果注册用户应在注册后登录,则为 1 或零 ("")
“dbAuth.passwordLength”:密码必须具有的最小长度(“12”)
“dbAuth.sessionName”:启动的 PHP 会话的名称(“”)
“wpAuth.mode”:如果您想允许匿名访问,则设置为“可选”(“必需”)
“wpAuth.wpDirectory”:可以找到 WordPress 安装的文件夹/路径(“.”)
“wpAuth.usernameFormField”:保存用户名的表单字段的名称(“username”)
“wpAuth.passwordFormField”:保存密码的表单字段的名称(“password”)
“jwtAuth.mode”:如果您想允许匿名访问,则设置为“可选”(“必需”)
“jwtAuth.header”:包含 JWT 令牌的标头名称(“X-Authorization”)
“jwtAuth.leeway”:可接受的时钟偏差秒数(“5”)
“jwtAuth.ttl”:令牌有效的秒数(“30”)
“jwtAuth.secrets”:用于使用(“”)签署 JWT 令牌的共享密钥
“jwtAuth.algorithms”:允许的算法,空表示“全部”(“”)
"jwtAuth.audiences": 允许的受众,空表示“全部”("")
“jwtAuth.issuers”:允许的颁发者,空表示“全部”(“”)
“jwtAuth.sessionName”:启动的 PHP 会话的名称(“”)
“basicAuth.mode”:如果您想允许匿名访问,则设置为“可选”(“必需”)
“basicAuth.realm”:显示登录时提示的文本(“需要用户名和密码”)
“basicAuth.passwordFile”:要读取的用户名/密码组合的文件(“.htpasswd”)
“basicAuth.sessionName”:启动的 PHP 会话的名称(“”)
“reconnect.driverHandler”:实现数据库驱动程序检索的处理程序(“”)
“reconnect.addressHandler”:实现数据库地址检索的处理程序(“”)
“reconnect.portHandler”:实现数据库端口检索的处理程序(“”)
“reconnect.databaseHandler”:实现数据库名称(“”)检索的处理程序
“reconnect.tablesHandler”:实现表名检索的处理程序(“”)
“reconnect.mappingHandler”:实现名称映射检索的处理程序(“”)
“reconnect.usernameHandler”:实现数据库用户名(“”)检索的处理程序
“reconnect.passwordHandler”:实现数据库密码检索的处理程序(“”)
“authorization.tableHandler”:实现表授权规则的处理程序(“”)
“authorization.columnHandler”:实现列授权规则的处理程序(“”)
“authorization.pathHandler”:实现路径授权规则的处理程序(“”)
“authorization.recordHandler”:实现记录授权过滤规则的处理程序(“”)
“validation.handler”:实现输入值验证规则的处理程序(“”)
“validation.types”:启用类型验证的类型,空表示“无”(“全部”)
“validation.tables”:启用类型验证的表,空表示“无”(“全部”)
“ipAddress.tables”:用于搜索要使用 IP 地址(“”)覆盖的列的表
“ipAddress.columns”:创建时用 IP 地址保护和覆盖的列(“”)
“sanitation.handler”:实现输入值卫生规则的处理程序(“”)
“sanitation.types”:启用类型清理的类型,空表示“无”(“全部”)
“sanitation.tables”:启用类型清理的表,空表示“无”(“全部”)
“multiTenancy.handler”:实现简单多租户规则的处理程序(“”)
“pageLimits.pages”:列表操作允许的最大页码(“100”)
“pageLimits.records”:列表操作返回的最大记录数(“1000”)
“joinLimits.depth”:连接路径中允许的最大深度(长度)(“3”)
“joinLimits.tables”:允许您加入的最大表数(“10”)
“joinLimits.records”:为连接实体返回的最大记录数(“1000”)
“textSearch.parameter”:用于搜索词(“搜索”)的参数名称
“customization.beforeHandler”:实现请求定制的Handler(“”)
“customization.afterHandler”:实现响应定制的处理程序(“”)
“json.controllers”:处理 JSON 字符串的控制器(“records,geojson”)
“json.tables”:处理 JSON 字符串的表(“all”)
“json.columns”:处理 JSON 字符串的列(“all”)
“xml.types”:应添加到 XML 类型属性的 JSON 类型(“null,array”)
如果您未在配置中指定这些参数,则使用默认值(括号之间)。
在下面的部分中,您可以找到有关内置中间件的更多信息。
目前支持五种类型的身份验证。它们都将经过身份验证的用户存储在$_SESSION
超级全局中。该变量可以在授权处理程序中使用来决定某人是否应该具有对某些表、列或记录的读或写访问权限。以下概述显示了您可以启用的身份验证中间件类型。
姓名 | 中间件 | 认证通过 | 用户存储在 | 会话变量 |
---|---|---|---|---|
API密钥 | apiKey认证 | “X-API-Key”标头 | 配置 | $_SESSION['apiKey'] |
API密钥数据库 | apiKeyDbAuth | “X-API-Key”标头 | 数据库表 | $_SESSION['apiUser'] |
数据库 | 数据库验证 | '/login' 端点 | 数据库表 | $_SESSION['user'] |
基本的 | 基本验证 | “授权”标头 | “.htpasswd”文件 | $_SESSION['username'] |
智威汤逊 | jwtAuth | “授权”标头 | 身份提供者 | $_SESSION['claims'] |
您可以在下面找到有关每种身份验证类型的更多信息。
API 密钥身份验证通过在请求标头中发送 API 密钥来进行。标头名称默认为“X-API-Key”,可以使用“apiKeyAuth.header”配置参数进行配置。必须使用“apiKeyAuth.keys”配置参数(逗号分隔列表)配置有效的 API 密钥。
X-API-Key: 02c042aa-c3c2-4d11-9dae-1a6e230ea95e
经过身份验证的 API 密钥将存储在$_SESSION['apiKey']
变量中。
请注意,API 密钥身份验证不需要或使用会话 cookie。
API 密钥数据库身份验证通过在请求标头“X-API-Key”(名称可配置)中发送 API 密钥来进行。有效的 API 密钥是从数据库的“users”表的“api_key”列中读取的(两个名称都是可配置的)。
X-API-Key: 02c042aa-c3c2-4d11-9dae-1a6e230ea95e
经过身份验证的用户(及其所有属性)将存储在$_SESSION['apiUser']
变量中。
请注意,API 密钥数据库身份验证不需要或使用会话 cookie。
数据库身份验证中间件定义了五个新路由:
method path - parameters - description --------------------------------------------------------------------------------------------------- GET /me - - returns the user that is currently logged in POST /register - username, password - adds a user with given username and password POST /login - username, password - logs a user in by username and password POST /password - username, password, newPassword - updates the password of the logged in user POST /logout - - logs out the currently logged in user
用户可以通过将用户名和密码发送到登录端点(JSON 格式)来登录。经过身份验证的用户(及其所有属性)将存储在$_SESSION['user']
变量中。用户可以通过向注销端点发送带有空正文的 POST 请求来注销。密码以散列形式存储在用户表的密码列中。您可以使用注册端点注册新用户,但必须使用“dbAuth.registerUser”配置参数打开此功能。
使用“授权”中间件限制对用户表的访问非常重要,否则所有用户都可以自由添加、修改或删除任何帐户!最小配置如下所示:
'middlewares' => 'dbAuth,authorization', 'authorization.tableHandler' => function ($operation, $tableName) { return $tableName != 'users'; },
请注意,此中间件使用会话 cookie 并将登录状态存储在服务器上。
使用带有连接表的视图登录
对于登录操作,可以使用视图作为 usersTable。这样的视图可以从用户表返回过滤结果,例如,其中active = true ,或者它也可以通过表连接返回多个表的结果。该视图至少应包含用户名和密码以及名为id 的字段。
但是,具有连接表的视图不可插入(请参阅问题 907)。作为解决方法,请使用属性loginTable为登录设置不同的参考表。 usersTable仍将设置为普通的可插入用户表。
Wordpress 身份验证中间件定义了三种路由:
method path - parameters - description --------------------------------------------------------------------------------------------------- GET /me - - returns the user that is currently logged in POST /login - username, password - logs a user in by username and password POST /logout - - logs out the currently logged in user
用户可以通过将用户名和密码发送到登录端点(JSON 格式)来登录。用户可以通过向注销端点发送带有空正文的 POST 请求来注销。您需要使用“wpAuth.wpDirectory”配置参数指定Wordpress安装目录。中间件调用“wp-load.php”,这允许您在授权中间件中使用 Wordpress 功能,例如:
wp_get_current_user()
is_user_logged_in()
is_super_admin()
user_can(wp_get_current_user(),'edit_posts');
请注意,该中间件不使用$_SESSION
变量。
基本类型支持一个文件(默认为“.htpasswd”),该文件保存用户及其(散列)密码,并用冒号(“:”)分隔。当密码以纯文本形式输入时,它们将被自动散列。经过身份验证的用户名将存储在$_SESSION['username']
变量中。您需要在“Basic”一词之后发送一个“Authorization”标头,其中包含冒号分隔的用户名和密码的 base64 url 编码版本。
Authorization: Basic dXNlcm5hbWUxOnBhc3N3b3JkMQ
此示例发送字符串“username1:password1”。
JWT 类型需要另一个(SSO/身份)服务器来签署包含声明的令牌。两台服务器共享一个秘密,以便它们可以签名或验证签名是否有效。声明存储在$_SESSION['claims']
变量中。您需要发送一个“X-Authorization”标头,其中包含 base64 url 编码和点分隔的令牌标头、正文和“Bearer”一词后面的签名(请在此处阅读有关 JWT 的更多信息)。标准规定您需要使用“Authorization”标头,但这在 Apache 和 PHP 中是有问题的。
X-Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6IjE1MzgyMDc2MDUiLCJleHAiOjE1MzgyMDc2MzV9.Z5px_GT15TRKhJCTHhDt5Z6K6LRDSFnLj8U5ok9l7gw
此示例发送签名的声明:
{ "sub": "1234567890", "name": "John Doe", "admin": true, "iat": "1538207605", "exp": 1538207635 }
注意:JWT 实现仅支持基于 RSA 和 HMAC 的算法。