🧭 路由与认证
后端路由使用 Spatie Route Attributes,模块扫描由 ModuleRegistry 统一生成。
🎯 本页目标
本页用于说明“接口地址从哪里来、哪些接口默认需要登录、公开接口怎么声明、前端应该怎么带 token”。新增接口前建议先读本页,避免出现接口地址不符合约定、公开接口误用普通 Get/Post、用户端公开接口被登录校验拦截等问题。
🔍 路由扫描
config/route-attributes.php:
'directories' => ModuleRegistry::routeAttributeDirectories(),扫描规则:
| 控制器目录 | 路由前缀 | 默认中间件 |
|---|---|---|
modules/{Module}/Http/Controllers/Admin | adminapi/{routePrefix} | admin.auth |
modules/{Module}/Http/Controllers/Api | api/{routePrefix} | api.site + api.auth |
{routePrefix} 由模块目录名规范化生成,例如 System 对应 system,UserCenter 对应 user-center。模块配置详见 模块配置。
示例:控制器位于 modules/System/Http/Controllers/Admin/Auth/LoginController.php ,路由分组注解为 #[Group(prefix: 'login')], 方法注解为 #[OpenPost('account')]:
#[Group(prefix: 'login')]
class LoginController extends ApiController
{
#[OpenPost('account', middleware: ['throttle:admin-login'])]
public function account(LoginRequest $form)
{
return success();
}
}最终接口通常就是:
POST /adminapi/system/login/account控制器位于 modules/System/Http/Controllers/Api/User/UserController.php ,路由分组注解为 #[Group(prefix: 'user')], 方法注解为 #[Get('info')]:
#[Group(prefix: 'user')]
class UserController extends ApiController
{
#[Get('info')]
public function info()
{
return success();
}
}最终接口通常就是:
GET /api/system/user/info由于 Api 目录默认已经挂载 api.site + api.auth,普通 Get/Post 用户端接口默认必须登录。用户地址、用户资料等强身份接口不需要再重复标注 api.auth。
🔓 公开接口
项目提供 OpenGet 和 OpenPost。它们会保留当前路由前缀,但自动排除对应认证中间件;在用户端 Api 目录中会排除 api.auth 登录校验,适合声明公开接口。
#[OpenPost('account', middleware: ['throttle:admin-login'])]
public function account(LoginRequest $form)
{
return success();
}适用场景:
- 后台登录、验证码。
- 后台初始化配置、语言包。
- 用户端文章、首页、搜索、公开配置。
公开接口只代表“不要求用户端登录态”,不代表不需要限流、验证码、签名或业务状态检查。登录、短信、AI 试用、上传直传等接口,应根据风险增加 throttle:*、验证码或业务校验。
🔒 必须登录接口
Admin 控制器默认需要管理员登录。Api 目录下普通 Get/Post 用户端接口也默认需要用户登录:
#[Get('logout')]
public function logout()
{
return success();
}认证后可通过 ApiController 获取身份:
$this->adminId();
$this->admin();
$this->userId();
$this->user();后台控制器默认已经套用 admin.auth,一般不需要重复写。用户端 Api 控制器默认已经套用 api.site + api.auth,一般也不需要重复写 api.auth。
use Spatie\RouteAttributes\Attributes\Get;
#[Get('profile/info')]
public function profile()
{
return success([
'user_id' => $this->userId(),
'nickname' => $this->user()->nickname,
]);
}🪪 尝试登录接口
如果接口允许游客访问,但登录后要返回更多个性化信息,可以使用 OpenGet/OpenPost 放开登录校验,再额外增加 api.try-auth:
#[OpenGet('article/detail', middleware: ['api.try-auth'])]
public function detail()
{
$user = $this->user();
return success([
'is_login' => filled($user),
]);
}api.try-auth 不会强制拦截游客。请求头携带有效 token 时会注入用户身份;没有 token 或 token 无效时,接口仍按游客逻辑继续执行。AI 聊天、上传等需要“游客可用、登录后增强”的接口使用该规则。
🧵 中间件语义
| 中间件 | 说明 |
|---|---|
admin.auth | Sanctum 管理员认证,要求模型为 Modules\System\Domain\Models\Auth\Admin |
api.auth | Sanctum 用户认证,要求模型为 Modules\System\Domain\Models\User\User |
api.try-auth | 尝试登录,携带有效 token 时注入用户,不强制拦截游客,对应 ApiTryAuthMiddleware |
api.site | 用户端站点状态检查,对应 ApiSiteStatusMiddleware |
throttle:* | 登录、短信、AI、上传等限流 |
ApiSiteStatusMiddleware
app/Core/Http/Middleware/ApiSiteStatusMiddleware.php
用户端站点开关检查。当后台"站点状态"配置为关闭时,所有用户端请求返回 HTTP 503。
检查流程:
- 判断是否已安装(检查
install.lock文件是否存在)。未安装时直接放行,避免阻断安装向导。 - 从
configs表读取basics.sys_status配置(通过ConfigDao,带缓存)。 - 值为
'0'、'false'、'off'时判定为关闭,返回 503 和关闭提示文案。 - 数据库或缓存异常时默认放行,不阻断正常访问。
相关配置(config/sunadmin.php 的 site_status 分组):
| 配置 | 默认值 | 说明 |
|---|---|---|
closed_message | '系统当前已关闭,请稍后再试' | 关闭时的提示文案 |
cache_key | 'sunadmin:site-status' | 缓存 key |
cache_ttl | 60 | 缓存秒数 |
group / key | 'basics' / 'sys_status' | 对应 configs 表的分组和键名 |
SetLocaleMiddleware
app/Core/Http/Middleware/SetLocaleMiddleware.php
从请求的 Accept-Language 头读取语言标识,设置 Laravel 应用语言环境。自动将 IETF 格式的 zh-CN 转换为 Laravel 使用的 zh_CN 下划线格式。
该中间件配合后端多语言系统工作,前端通过 X-Language 请求头或 Accept-Language 传递当前语言。多语言详细机制见 多语言系统。
🪪 Token 传递方式
Admin 和 uni-app 均使用 Bearer Token:
Authorization: Bearer {token}后端不建议从普通请求字段里读取 token。前端请求封装会统一放入请求头,接口只需要依赖对应认证中间件和控制器基类提供的身份方法。
🚪 登录接口
Admin:
| 方法 | URI | 说明 |
|---|---|---|
GET | /adminapi/system/login/captchaConfig | 验证码配置 |
POST | /adminapi/system/login/checkCaptcha | 校验验证码 |
POST | /adminapi/system/login/account | 账号密码登录 |
POST | /adminapi/system/login/logout | 退出登录,需管理员 token |
用户端:
| 方法 | URI | 说明 |
|---|---|---|
POST | /api/system/login/account | 用户登录 |
GET | /api/system/login/logout | 退出登录,需用户 token |
用户端登录参数由 AccountLoginRequest 约束:
| 字段 | 说明 |
|---|---|
terminal | 终端:微信小程序 1、微信公众号 2、H5 3 |
scene | 登录场景:密码、短信、手机号授权、微信静默等 |
mobile | 手机号 |
password | 密码 |
code | 短信验证码 |
authPhoneCode | 小程序手机号授权 code |
loginCode | 微信登录 code |
🔬 常见注意事项
- 公开性由
OpenGet/OpenPost表达。 - Api 目录普通
Get/Post默认必须登录,用户资料、地址等接口不要重复标注api.auth。 - 允许游客访问但希望识别登录态的接口,使用
OpenGet/OpenPost+api.try-auth。 - 熟悉模块路由加载规则,Admin 和 uni-app 已按约定
/adminapi/{routePrefix}/*、/api/{routePrefix}/*调用。 - 菜单动态路由依赖后台菜单中的组件路径,后端菜单和前端
views路径要同步。
完整注解签名、参数说明与自定义扩展方式见 代码注解。
