zcclxx/tp6-api-foundation

ThinkPHP 6 API 基座:可插拔登录解析、request 注入用户、CRUD Logic 封装(可选 JWT)

Maintainers

Package info

gitee.com/zcclxx/thinkphp6-baseapi.git

pkg:composer/zcclxx/tp6-api-foundation

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

1.0.2 2026-05-15 08:23 UTC

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
ApiBaseControlleruser() / logicFor() / jsonSuccess() / jsonError()
CrudLogic按当前用户过滤的列表、详情、增删改
ApiResponse统一 { code, msg, data?, time } 结构
控制台命令脚手架生成多应用、安装 users

安装

1. Composer 引入

本地 path 仓库(开发本包): 在项目 composer.jsonrepositories 中增加:

{
    "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:discoverthink 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_keySession 中存放用户 ID 的键(SessionAuthProvider
trusted_header_user_id内网网关透传用户 ID 的 Header 名,如 X-User-Id;留空不启用
jwt_token_version_fieldJWT 与库中比对防踢字段,默认 token_version;无字段则跳过
auth_providers认证提供者类名数组,按顺序尝试,第一个返回用户即成功
auth_requiredtrue:中间件无用户时直接返回未登录 JSON;false:仅不写 authUser,由控制器处理
unauthorized_code未登录时的业务 code,默认 888
response.success_code / response.error_code_default成功/默认失败业务码

默认 auth_providers 顺序:

  1. RequestAttributeAuthProvider — 已有 request->authUser 时直接采用
  2. TrustedHeaderUserIdProvider — 读取 trusted_header_user_id 指定 Header
  3. SessionAuthProvider — 读 Session 中的用户 ID
  4. JwtAuthProvider — 解析 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(模型类, 身份字段) 创建实例。第二个参数为按当前用户过滤的字段名(常见为 iduser_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(推荐移动端 / 前后端分离)

  1. 安装并配置 thans/tp-jwt-auth
  2. 业务登录接口校验通过后签发 token(payload 建议含 idtoken_version
  3. 客户端请求头:Authorization: Bearer <token>
  4. 修改密码/踢下线时递增用户表 token_version,旧 token 自动失效

内网网关 Header

仅在内网、网关已鉴权时使用:

'trusted_header_user_id' => 'X-User-Id',

网关设置:X-User-Id: 123。生产环境勿对公网暴露。

第三方 OAuth(微信等)

扩展不内置微信/支付宝 SDK。典型流程:

  1. 业务接口用官方 SDK 用 codeopenid(或 unionid)
  2. 查/建 users 表记录(openid 字段存第三方标识,亦可只用 phone
  3. 按上表写入 Session 或签发 JWT

install_users.mysql.sqlopenid可空字段,仅在有第三方账号体系时使用;纯手机号/账号密码项目可忽略该字段。

部分接口免登录

方式 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.phpauth_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.phpmiddleware.phpevent.php
  • app/{name}/controller/Index.php
  • app/{name}/controller/v1/Profile.phpDemo.php
  • route/{name}.php — 示例路由

生成后确认 config/app.phpdeny_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 包使用。不会自动改动你现有项目的控制器、路由或模型;接入步骤由你在目标项目中按需执行:

  1. composer require zcclxx/tp6-api-foundation(或 path 仓库指向本目录)
  2. 发布并编辑 config/tp6_api_foundation.php(设置 user_model 等)
  3. config/middleware.php 注册别名 tp6_api_auth
  4. 新接口继承 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