API 安全

XinAdmin 通过中间件链、注解路由、请求校验和异常处理构建了完整的 API 安全体系。

路由中间件

所有受保护的 API 路由采用三重中间件:

// 标准受保护路由
Route::get('/system/user', [SysUserController::class, 'index'])
    ->middleware(['auth:sanctum', 'authGuard', 'abilities:system.user.query']);
中间件类型作用
auth:sanctumLaravel Sanctum验证 Bearer Token
authGuard自定义验证 Token 类型匹配(防止跨模型 Token 滥用)
abilities:{key}Laravel Sanctum验证 Token 的能力列表中包含指定权限

AnnoRoute 注解路由

XinAdmin 提供了 AnnoRoute 注解路由系统,通过 PHP 8 注解自动注册路由和权限中间件,避免手动编写路由定义和中间件配置:

#[RequestAttribute('/system/user', 'system.user')]
class SysUserController
{
    #[GetRoute(authorize: 'query')]
    public function index() { ... }  // 自动添加 abilities:system.user.query

    #[PostRoute(authorize: 'create')]
    public function store() { ... }  // 自动添加 abilities:system.user.create

    #[PutRoute(authorize: 'update')]
    public function update() { ... } // 自动添加 abilities:system.user.update

    #[DeleteRoute(authorize: 'delete')]
    public function destroy() { ... } // 自动添加 abilities:system.user.delete
}

注解参数

注解参数说明
RequestAttributeprefix, abilitiesPrefix路由前缀 + 权限 key 前缀
GetRouteauthorize, uriGET 路由,自动拼接权限 key
PostRouteauthorize, uriPOST 路由
PutRouteauthorize, uriPUT 路由
DeleteRouteauthorize, uriDELETE 路由

RouteRegisterService 在启动时扫描所有带注解的控制器,自动调用 Laravel 路由注册并附加 ['auth:sanctum', 'authGuard', 'abilities:{prefix}.{authorize}'] 中间件。

未授权处理

当用户 Token 缺少所需权限时,ExceptionsHandler 捕获 MissingAbilityException 并返回:

{
  "success": false,
  "showType": 2,
  "msg": "No Permission"
}

其他安全相关异常处理:

异常返回信息HTTP 状态码
AuthenticationException请先登录401
MissingAbilityExceptionNo Permission403
NotFoundHttpException路由不存在404
ValidationException第一条校验错误信息422

CORS 跨域安全

全局 CORS 中间件 AllowCrossDomainMiddleware

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, User-Language
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1800

处理 OPTIONS 预检请求返回 204 状态码。异常处理器中也重复设置了 CORS 头作为兜底。

请求校验

所有表单请求继承 BaseFormRequest,提供统一的验证规则:

校验类说明
SysUserFormRequest用户创建/编辑校验(用户名、邮箱、密码格式)
SysRoleFormRequest角色校验(名称必填)
SysRuleFormRequest权限规则校验(类型、key 唯一性、父级存在性)

验证失败时返回:

{
  "success": false,
  "showType": 1,
  "msg": "第一条校验错误信息"
}

新增受保护接口

为系统添加新的受保护接口的步骤:

1. 在权限规则表添加记录

sys_rule 表中新增一条 type=rule 的记录,key 为对应权限标识,如 my.module.action

2. 定义路由并附加中间件

Route::post('/my-module/action', [MyController::class, 'action'])
    ->middleware(['auth:sanctum', 'authGuard', 'abilities:my.module.action']);

3. 前端添加权限控制

<AuthButton auth="my.module.action">
  <Button>操作</Button>
</AuthButton>

生产环境安全建议

建议说明
关闭调试模式.env 中设置 APP_DEBUG=false,避免泄露堆栈信息
启用 HTTPS防止 Token 在传输中被截获
限制 CORS生产环境将 Access-Control-Allow-Origin 设为具体域名,而非 *
增强密码策略SysUserFormRequest 中提高密码复杂度要求
速率限制为登录等敏感接口添加 Laravel Rate Limiting 中间件
Session 安全http_only=truesame_site=lax 已在 Session 配置中启用