zcclxx / tp6-api-foundation
ThinkPHP 6 API 基座:可插拔登录解析、request 注入用户、CRUD Logic 封装(可选 JWT)
Requires
- php: >=7.2
- topthink/framework: ^6.0
Suggests
- thans/tp-jwt-auth: 启用 JwtAuthProvider 解析 Bearer JWT
This package is not auto-updated.
Last update: 2026-05-16 06:43:39 UTC
README
ThinkPHP 6 API 基座扩展:可插拔登录态解析、请求注入当前用户、CrudLogic 数据权限封装、统一 JSON 响应。
说明: 本包不负责「怎么登录」(账号密码、短信验证码、微信/支付宝/Apple 等第三方 OAuth 均由业务实现);只负责在用户已登录后,从 Session / JWT / 网关 Header 等渠道识别当前用户并注入 request->authUser。JWT 为可选依赖。
功能概览
| 模块 | 说明 |
|---|---|
ApiAuthMiddleware | 按配置链式解析用户,写入 $request->authUser |
ApiBaseController | user() / logicFor() / jsonSuccess() / jsonError() |
CrudLogic | 按当前用户过滤的列表、详情、增删改 |
ApiResponse | 统一 { code, msg, data?, time } 结构 |
| 控制台命令 | 脚手架生成多应用、安装 users 表 |
安装
1. Composer 引入
本地 path 仓库(开发本包): 在项目 composer.json 的 repositories 中增加:
{
"type": "path",
"url": "packages/tp6-api-foundation",
"options": { "symlink": true }
}
然后执行:
composer require zcclxx/tp6-api-foundation:^1.0
已发布到 Packagist 时: 直接 composer require zcclxx/tp6-api-foundation,无需 path 仓库。
安装后会自动执行 think service:discover 与 think vendor:publish,发布配置文件到项目根目录 config/tp6_api_foundation.php。
2. 可选:JWT
需要 Bearer Token 鉴权时安装:
composer require thans/tp-jwt-auth
并按 tp-jwt-auth 文档 配置。未安装时 JwtAuthProvider 会自动跳过,不报错。
3. 注册中间件别名
在 config/middleware.php 中增加:
'alias' => [
'tp6_api_auth' => \Zcclxx\Tp6Api\Middleware\ApiAuthMiddleware::class,
],
4. 业务配置
编辑 config/tp6_api_foundation.php,至少指定用户模型:
'user_model' => \app\admin\model\Users::class,
其余项见下方「配置说明」。
5. 数据库(可选)
若尚无与 Users 模型一致的表,可执行:
php think tp6-api:install-users-table
# 仅预览 SQL
php think tp6-api:install-users-table --dry-run
# 指定连接
php think tp6-api:install-users-table -c mysql
会创建带 token_version 字段的 users 表(表前缀取自 config/database.php)。
配置说明
配置文件:config/tp6_api_foundation.php(由 vendor 默认配置发布,可覆盖)。
| 配置项 | 说明 |
|---|---|
user_model | 用户模型类名,须能 find() 并按主键查询 |
session_user_id_key | Session 中存放用户 ID 的键(SessionAuthProvider) |
trusted_header_user_id | 内网网关透传用户 ID 的 Header 名,如 X-User-Id;留空不启用 |
jwt_token_version_field | JWT 与库中比对防踢字段,默认 token_version;无字段则跳过 |
auth_providers | 认证提供者类名数组,按顺序尝试,第一个返回用户即成功 |
auth_required | true:中间件无用户时直接返回未登录 JSON;false:仅不写 authUser,由控制器处理 |
unauthorized_code | 未登录时的业务 code,默认 888 |
response.success_code / response.error_code_default | 成功/默认失败业务码 |
默认 auth_providers 顺序:
RequestAttributeAuthProvider— 已有request->authUser时直接采用TrustedHeaderUserIdProvider— 读取trusted_header_user_id指定 HeaderSessionAuthProvider— 读 Session 中的用户 IDJwtAuthProvider— 解析 JWT(需安装 tp-jwt-auth)
可按场景删减或调整顺序,例如纯 JWT API 可只保留 JwtAuthProvider。
快速使用
控制器继承基类 + 中间件
<?php
declare(strict_types=1);
namespace app\api\controller\v1;
use app\admin\model\Users;
use Zcclxx\Tp6Api\Controller\ApiBaseController;
class Profile extends ApiBaseController
{
protected $middleware = [
'tp6_api_auth',
];
public function me()
{
$logic = $this->logicFor(Users::class, 'id');
$logic->field = ['id', 'nickname', 'avatar', 'phone'];
$row = $logic->getOne([], 1); // auth=1:仅查当前用户
return $row ? $this->jsonSuccess($row) : $this->jsonError('用户不存在');
}
}
路由示例(route/api.php):
Route::get('userinfo/me', 'api/v1/Userinfo/me');
当前用户
- 中间件解析后:
$this->request->authUser或$this->user() user()返回模型/array;异常时返回 字符串 错误信息(与旧Api控制器兼容)isLogin()判断是否已登录
统一响应
成功:
{ "code": 1, "msg": "成功", "data": {}, "time": "2026-05-15 12:00:00" }
失败(未登录示例):
{ "code": "888", "msg": "未登录或登录已失效", "time": "2026-05-15 12:00:00" }
也可直接使用 Zcclxx\Tp6Api\Support\ApiResponse::success() / ::error()。
CrudLogic 数据权限
通过 logicFor(模型类, 身份字段) 创建实例。第二个参数为按当前用户过滤的字段名(常见为 id 或 user_id);传 null 表示创建时不自动写入用户字段。
| 方法 | $auth 含义 |
|---|---|
null | 不按用户过滤 |
1 | 仅当前登录用户(identityField in [当前用户id]) |
| 其他 | 同上,用于强制数据范围 |
常用方法:
getPageList($where, $auth, $order, $pageSize)— 分页列表getOne($where, $auth, $with)— 单条(带行锁)create_one($data, $auth)— 新增update_one($data, $id, $auth)— 更新(先校验归属)delete_one($id, $auth)— 删除(先校验归属)
设置 $logic->field = [...] 限制查询字段;$logic->withoutField 排除字段。
脚手架生成的 app/{应用名}/controller/v1/Demo.php 内含完整 CRUD 示例(执行 php think tp6-api:app 后查看)。
登录与鉴权(两层分工)
| 层次 | 谁负责 | 典型做法 |
|---|---|---|
| 业务登录 | 你的项目 | 账号+密码、短信验证码、邮箱、第三方 OAuth(微信/支付宝/Apple/Google 等)、扫码、单点登录 |
| 登录态解析 | 本扩展 auth_providers | 从 Session / JWT / 内网 Header 读出用户 ID,加载 user_model 写入 authUser |
业务登录成功后,任选一种方式让后续请求被识别:
Session(H5 / 传统 Web)
// 业务校验账号密码/短信/第三方 OAuth 通过后:
session(config('tp6_api_foundation.session_user_id_key'), $userId);
保证 auth_providers 包含 SessionAuthProvider。
JWT(推荐移动端 / 前后端分离)
- 安装并配置
thans/tp-jwt-auth - 业务登录接口校验通过后签发 token(payload 建议含
id、token_version) - 客户端请求头:
Authorization: Bearer <token> - 修改密码/踢下线时递增用户表
token_version,旧 token 自动失效
内网网关 Header
仅在内网、网关已鉴权时使用:
'trusted_header_user_id' => 'X-User-Id',
网关设置:X-User-Id: 123。生产环境勿对公网暴露。
第三方 OAuth(微信等)
扩展不内置微信/支付宝 SDK。典型流程:
- 业务接口用官方 SDK 用
code换openid(或 unionid) - 查/建
users表记录(openid字段存第三方标识,亦可只用phone) - 按上表写入 Session 或签发 JWT
install_users.mysql.sql 中 openid 为可空字段,仅在有第三方账号体系时使用;纯手机号/账号密码项目可忽略该字段。
部分接口免登录
方式 A: 控制器不加 tp6_api_auth,在方法内自行判断 isLogin()。
方式 B: 全局 auth_required => false,需登录的控制器再加中间件。
方式 C: 路由分组:公开路由不挂中间件,受保护路由挂 tp6_api_auth。
自定义认证提供者
实现 Zcclxx\Tp6Api\Auth\AuthUserProviderInterface:
<?php
namespace app\api\auth;
use think\Request;
use Zcclxx\Tp6Api\Auth\AuthUserProviderInterface;
class MyAuthProvider implements AuthUserProviderInterface
{
public function resolve(Request $request)
{
// 解析成功返回用户模型或数组,失败返回 null
return null;
}
}
在 config/tp6_api_foundation.php 的 auth_providers 数组最前面加入该类名。
控制台命令
脚手架:新建多应用 API 模块
php think tp6-api:app openapi
php think tp6-api:app myapi -f # 覆盖已存在文件
php think tp6-api:app myapi --no-route # 不生成 route/myapi.php
生成内容:
app/{name}/—common.php、middleware.php、event.phpapp/{name}/controller/Index.phpapp/{name}/controller/v1/Profile.php、Demo.phproute/{name}.php— 示例路由
生成后确认 config/app.php 的 deny_app_list 未禁止该应用名。
访问示例(应用名 openapi):
GET /openapi/v1/profile/me— 当前用户GET /openapi/v1/demo/index— 演示列表
安装用户表
php think tp6-api:install-users-table
接入现有 ThinkPHP 6 项目(不修改业务代码时)
本仓库中的 扩展包目录 packages/tp6-api-foundation/ 可单独拷贝或作为 Composer path / Packagist 包使用。不会自动改动你现有项目的控制器、路由或模型;接入步骤由你在目标项目中按需执行:
composer require zcclxx/tp6-api-foundation(或 path 仓库指向本目录)- 发布并编辑
config/tp6_api_foundation.php(设置user_model等) - 在
config/middleware.php注册别名tp6_api_auth - 新接口继承
ApiBaseController并挂中间件;原有app\api\controller\Api等代码可保持不变,逐步迁移即可
也可运行 php think tp6-api:app 应用名 生成新的应用目录与示例路由,与现有 api 应用并行,互不影响。
目录结构
packages/tp6-api-foundation/
├── config/tp6_api_foundation.php # 默认配置(发布到项目 config/)
├── database/install_users.mysql.sql
├── stubs/ # tp6-api:app 模板
└── src/
├── Auth/ # 认证提供者
├── Command/ # 控制台命令
├── Controller/ApiBaseController.php
├── Logic/CrudLogic.php
├── Middleware/ApiAuthMiddleware.php
├── Support/ApiResponse.php
└── Tp6ApiService.php # 服务注册
许可证
MIT