在 Laravel Swagger 中集成认证支持
在 Swagger/OpenAPI 中添加认证支持对于文档非常重要,它允许用户直接在文档界面测试需要认证的端点。以下是完整的集成方案:
完整解决方案
1. 定义安全方案
在你的控制器文件顶部添加安全方案定义:
/**
* @OA\OpenApi(
* security={{"bearerAuth":{}}}
* )
*
* @OA\SecurityScheme(
* securityScheme="bearerAuth",
* type="http",
* scheme="bearer",
* bearerFormat="JWT"
* )
*
* @OA\SecurityScheme(
* securityScheme="apiKey",
* type="apiKey",
* in="header",
* name="X-API-Key"
* )
*/
class ApiController extends Controller
{
// 控制器代码...
}
2. 在端点中添加安全要求
在需要认证的端点中添加安全要求:
/**
* @OA\Get(
* path="/api/user/profile",
* tags={"User"},
* summary="获取用户个人信息",
* security={{"bearerAuth":{}}},
* @OA\Response(
* response=200,
* description="成功响应",
* @OA\JsonContent(ref="#/components/schemas/User")
* ),
* @OA\Response(
* response=401,
* description="未认证",
* @OA\JsonContent(ref="#/components/schemas/ErrorResponse")
* )
* )
*/
public function getUserProfile()
{
// 控制器代码...
}
3. 定义认证响应模型
添加认证相关的响应模型:
/**
* @OA\Schema(
* schema="LoginRequest",
* required={"email", "password"},
* @OA\Property(property="email", type="string", format="email", example="user@example.com"),
* @OA\Property(property="password", type="string", example="password123")
* )
*
* @OA\Schema(
* schema="LoginResponse",
* @OA\Property(property="access_token", type="string", example="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."),
* @OA\Property(property="token_type", type="string", example="Bearer"),
* @OA\Property(property="expires_in", type="integer", example=3600)
* )
*
* @OA\Schema(
* schema="ErrorResponse",
* @OA\Property(property="error", type="string", example="Unauthorized"),
* @OA\Property(property="message", type="string", example="Authentication failed"),
* @OA\Property(property="code", type="integer", example=401)
* )
*/
4. 创建认证端点文档
为登录端点添加文档:
/**
* @OA\Post(
* path="/api/auth/login",
* tags={"Authentication"},
* summary="用户登录",
* description="通过邮箱和密码获取访问令牌",
* operationId="authLogin",
* security={},
* @OA\RequestBody(
* required=true,
* @OA\JsonContent(ref="#/components/schemas/LoginRequest")
* ),
* @OA\Response(
* response=200,
* description="登录成功",
* @OA\JsonContent(ref="#/components/schemas/LoginResponse")
* ),
* @OA\Response(
* response=401,
* description="认证失败",
* @OA\JsonContent(ref="#/components/schemas/ErrorResponse")
* )
* )
*/
public function login(Request $request)
{
// 登录逻辑...
}
5. 添加刷新令牌端点文档
/**
* @OA\Post(
* path="/api/auth/refresh",
* tags={"Authentication"},
* summary="刷新访问令牌",
* description="使用刷新令牌获取新的访问令牌",
* operationId="authRefresh",
* security={},
* @OA\Response(
* response=200,
* description="令牌刷新成功",
* @OA\JsonContent(ref="#/components/schemas/LoginResponse")
* ),
* @OA\Response(
* response=401,
* description="无效的刷新令牌",
* @OA\JsonContent(ref="#/components/schemas/ErrorResponse")
* )
* )
*/
public function refresh()
{
// 刷新令牌逻辑...
}
6. 添加登出端点文档
/**
* @OA\Post(
* path="/api/auth/logout",
* tags={"Authentication"},
* summary="用户登出",
* description="使当前访问令牌失效",
* operationId="authLogout",
* security={{"bearerAuth":{}}},
* @OA\Response(
* response=200,
* description="登出成功",
* @OA\JsonContent(
* @OA\Property(property="message", type="string", example="Successfully logged out")
* )
* ),
* @OA\Response(
* response=401,
* description="未认证",
* @OA\JsonContent(ref="#/components/schemas/ErrorResponse")
* )
* )
*/
public function logout()
{
// 登出逻辑...
}
7. 全局认证设置 (config/l5-swagger.php)
在配置文件中添加全局认证设置:
return [
// ...
'swagger_security' => [
'bearerAuth' => [
'type' => 'http',
'scheme' => 'bearer',
'bearerFormat' => 'JWT',
],
'apiKey' => [
'type' => 'apiKey',
'name' => 'X-API-Key',
'in' => 'header',
],
],
'security' => [
[
'bearerAuth' => [],
],
],
];
使用说明
- 在 Swagger UI 中,点击右上角的 Authorize 按钮
- 对于 Bearer 认证:
- 输入访问令牌(不包括 “Bearer” 前缀)
- 点击 Authorize
- 对于 API Key 认证:
- 在值字段中输入您的 API 密钥
- 点击 Authorize
高级技巧
1. 权限控制文档
/**
* @OA\Get(
* path="/api/admin/users",
* tags={"Admin"},
* summary="获取所有用户 (仅管理员)",
* security={
* {"bearerAuth":{}},
* {"apiKey":{}}
* },
* @OA\Response(
* response=200,
* description="成功响应",
* @OA\JsonContent(type="array", @OA\Items(ref="#/components/schemas/User"))
* ),
* @OA\Response(
* response=403,
* description="禁止访问",
* @OA\JsonContent(ref="#/components/schemas/ErrorResponse")
* )
* )
*/
public function getAllUsers()
{
// 需要管理员权限...
}
2. OAuth2 支持
/**
* @OA\SecurityScheme(
* securityScheme="oauth2",
* type="oauth2",
* @OA\Flow(
* authorizationUrl="/oauth/authorize",
* tokenUrl="/oauth/token",
* flow="authorizationCode",
* scopes={
* "read": "读取权限",
* "write": "写入权限",
* "admin": "管理员权限"
* }
* )
* )
*/
3. 刷新令牌控制器示例
public function refresh()
{
try {
$newToken = auth()->refresh();
return response()->json([
'access_token' => $newToken,
'token_type' => 'bearer',
'expires_in' => auth()->factory()->getTTL() * 60
]);
} catch (\Exception $e) {
return response()->json([
'error' => 'token_expired',
'message' => '刷新令牌已过期',
'code' => 401
], 401);
}
}
最佳实践
- 统一认证响应格式:确保所有认证错误返回相同的结构
- 文档版本控制:添加认证方式到API版本信息中
- 范围标注:对OAuth2认证添加权限范围说明
- 测试账号:在文档描述中添加测试用的账号信息
- 令牌生命周期:在文档中说明令牌的有效期和刷新机制
- 安全建议:添加关于安全存储令牌的说明
通过以上配置,Swagger文档将支持完整的认证流程,可以直接在文档界面进行认证并测试受保护的API端点。