# laravel-native-api **Repository Path**: yssk/laravel-native-api ## Basic Information - **Project Name**: laravel-native-api - **Description**: 基于 Redis 的认证系统:提供安全的令牌认证机制,支持 IP 验证 统一异常处理:自动处理 API 异常并返回一致的响应格式 RESTful 响应:遵循 RESTful API 设计原则,使用标准 HTTP 状态码 多语言支持:支持中英文双语,可通过配置切换 灵活的配置:通过配置文件自定义所有参数 - **Primary Language**: PHP - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-24 - **Last Updated**: 2025-12-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Laravel Native API Package 一个为 Laravel 12 应用提供原生 API 功能的包,包含异常处理、认证、响应格式化等功能。 ## 功能特性 - **基于 Redis 的认证系统**:提供安全的令牌认证机制,支持 IP 验证 - **统一异常处理**:自动处理 API 异常并返回一致的响应格式 - **RESTful 响应**:遵循 RESTful API 设计原则,使用标准 HTTP 状态码 - **多语言支持**:支持中英文双语,可通过配置切换 - **灵活的配置**:通过配置文件自定义所有参数 ## 安装 ```bash composer require sysc/laravel-native-api ``` ## 配置 ### 1. 发布配置文件 ```bash php artisan vendor:publish --provider="Sysc\LaravelNativeApi\ApiServiceProvider" --tag="api-config" ``` ### 2. 发布语言文件(可选) ```bash php artisan vendor:publish --provider="Sysc\LaravelNativeApi\ApiServiceProvider" --tag="api-lang" ``` ### 3. 配置 Redis 确保在 `.env` 文件中配置了 Redis 连接: ```env REDIS_CLIENT=phpredis REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 ``` ### 4. 配置异常处理 在 `bootstrap/app.php` 中添加异常处理注册: ```php use Sysc\LaravelNativeApi\Exceptions\ExceptionHandlerRegistrar; // ... ->withExceptions(function (Exceptions $exceptions) { ExceptionHandlerRegistrar::registerApiHandlers($exceptions); })->create(); ``` 或者使用包提供的命令自动配置: ```bash php artisan api:setup-exception-handler ``` ## 使用 ### 认证系统 包提供完整的基于 Redis 的认证系统: #### 登录 POST `/api/auth/login` ```json { "username": "your_username", "password": "your_password" } ``` 响应: ```json { "message": "登录成功", "data": { "access_token": "your_access_token", "token_type": "Bearer", "expires_in": 7200, "refresh_token": "your_refresh_token" }, "timestamp": "2025-12-23T00:00:00.000000Z" } ``` #### 刷新令牌 POST `/api/auth/refresh` ```json { "refresh_token": "your_refresh_token" } ``` #### 获取用户信息 GET `/api/auth/me` 需要在请求头中包含 Bearer Token #### 登出 POST `/api/auth/logout` 需要在请求头中包含 Bearer Token ### 在控制器中使用响应 Trait 在你的控制器中使用 `ApiResponseTrait`: ```php 'Hello World']; // 返回成功响应 return $this->success($data, 'success', [], 200); // 返回错误响应 return $this->error('error', [], 400); // 返回未授权响应 return $this->unauthorized('unauthorized'); } } ``` ### 在路由中使用认证中间件 ```php use Sysc\LaravelNativeApi\Http\Middleware\AuthenticateWithToken; Route::middleware([AuthenticateWithToken::class])->group(function () { // 受保护的路由 Route::get('/protected', function () { return response()->json(['message' => 'This is protected']); }); }); ``` ## 配置选项 在 `config/api.php` 中可以配置以下选项: ```php '1.0', // 异常处理配置 'exceptions' => [ 'enabled' => true, 'handlers' => [ // 异常处理器类 ], ], // 响应配置 'response' => [ 'format' => 'json', 'include_debug_info' => env('APP_DEBUG', false), 'default_error_message' => 'An error occurred', 'language' => env('API_LANGUAGE', 'en'), // 'en' or 'zh' ], // 令牌配置 'token' => [ 'access_expires' => env('API_TOKEN_ACCESS_EXPIRES', 7200), // 访问令牌过期时间(秒) 'refresh_expires' => env('API_TOKEN_REFRESH_EXPIRES', 604800), // 刷新令牌过期时间(秒) 'access_length' => env('API_TOKEN_ACCESS_LENGTH', 64), // 访问令牌长度 'refresh_length' => env('API_TOKEN_REFRESH_LENGTH', 128), // 刷新令牌长度 'access_prefix' => env('API_TOKEN_ACCESS_PREFIX', 'access_token:'), // 访问令牌前缀 'refresh_prefix' => env('API_TOKEN_REFRESH_PREFIX', 'refresh_token:'), // 刷新令牌前缀 'user_refresh_prefix' => env('API_TOKEN_USER_REFRESH_PREFIX', 'user_refresh_tokens:'), // 用户刷新令牌集合前缀 'user_model' => env('API_USER_MODEL', \App\Models\User::class), // 用户模型类 ], ]; ``` ## 异常处理 包自动处理以下类型的异常: - 验证异常 - 认证异常 - 授权异常 - 模型未找到异常 - 404 异常 - 其他未处理异常 所有异常都会返回统一的响应格式。 ## 多语言支持 通过在 `.env` 文件中设置 `API_LANGUAGE` 来切换语言: ```env API_LANGUAGE=en # 英文 API_LANGUAGE=zh # 中文 ``` ## 安全说明 ### IP 绑定 本包使用 IP 绑定机制来增强安全性: - 每个访问令牌都与用户的 IP 地址相关联 - 当用户使用令牌进行请求时,系统会验证请求的 IP 地址是否与令牌创建时的 IP 地址匹配 - 如果 IP 地址不匹配,请求将被拒绝,防止令牌被盗用后在其他地方使用 > **注意**:IP 绑定机制在以下场景中特别有效: > > - 防止令牌被中间人攻击获取后滥用 > - 限制令牌只能在特定网络环境中使用 > - 增加额外的安全层,即使令牌泄露也难以在其他地方使用 > **注意事项**:对于移动应用或使用移动网络的用户,IP 地址可能会发生变化,这可能导致合法用户的请求被拒绝。在这些场景中,可能需要调整 IP 验证策略。 ## 性能提示 ### Redis 连接要求 为了确保认证系统的最佳性能,请注意以下要求: 1. **Redis 服务器位置**:建议将 Redis 服务器部署在与应用服务器相同的网络环境中,以减少网络延迟。 2. **连接池配置**:在高并发环境下,建议配置适当的 Redis 连接池: ```env REDIS_CLUSTER=redis-cluster REDIS_CLIENT=phpredis ``` 3. **内存配置**:根据预期的用户数量配置足够的 Redis 内存,因为每个活跃用户的令牌都会存储在 Redis 中。 4. **持久化策略**:虽然令牌可以重新生成,但建议配置适当的 Redis 持久化策略以防数据丢失。 5. **连接超时设置**:在 `config/database.php` 中适当调整 Redis 连接超时设置: ```php 'redis' => [ 'client' => env('REDIS_CLIENT', 'phpredis'), 'options' => [ 'cluster' => env('REDIS_CLUSTER', 'redis'), 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'database'), ], 'default' => [ 'url' => env('REDIS_URL'), 'host' => env('REDIS_HOST', '127.0.0.1'), 'password' => env('REDIS_PASSWORD', null), 'port' => env('REDIS_PORT', '6379'), 'database' => env('REDIS_DB', '0'), 'read_timeout' => 60, // 增加读取超时时间 ], ], ``` ## 命令 包提供以下 Artisan 命令: 自动配置异常处理 ```bash php artisan api:setup-exception-handler ``` ## 自定义 ### 自定义用户模型 通过修改配置文件中的 `token.user_model` 选项来使用自定义用户模型: ```php 'token' => [ 'user_model' => \App\Models\CustomUser::class, ], ``` ### 自定义令牌配置 所有令牌相关配置都可以在 `config/api.php` 中自定义,包括过期时间、长度、前缀等。 ## ENV配置 ```env # API 配置 API_LANGUAGE=zh # 令牌配置 API_TOKEN_ACCESS_EXPIRES=7200 API_TOKEN_REFRESH_EXPIRES=604800 API_TOKEN_ACCESS_LENGTH=64 API_TOKEN_REFRESH_LENGTH=128 API_TOKEN_ACCESS_PREFIX=access_token: API_TOKEN_REFRESH_PREFIX=refresh_token: API_TOKEN_USER_REFRESH_PREFIX=user_refresh_tokens: API_USER_MODEL=App\Models\User # CORS 配置 CORS_ALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000 CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE,OPTIONS CORS_ALLOWED_HEADERS=Content-Type,Authorization,X-Requested-With,Accept,Origin CORS_EXPOSED_HEADERS= CORS_MAX_AGE=0 CORS_SUPPORTS_CREDENTIALS=true ``` ## Composer 安装 ```json "repositories": [ { "type": "git", "url": "https://gitee.com/yssk/laravel-native-api.git" } ] ``` ## 增加 ```` php protected function paginated($data, $key = 'success', array $replace = [], int $statusCode = 200) { // 检查第二个参数是否为 transformer 实例 $transformer = null; if ($key instanceof TransformerAbstract) { $transformer = $key; $key = 'success'; // 设置默认消息键 } $message = $this->trans($key, $replace); // 如果提供了 transformer,转换数据 if ($transformer && $data instanceof \Illuminate\Pagination\LengthAwarePaginator) { $transformedData = $data->getCollection()->map(function ($item) use ($transformer) { return $transformer->transform($item); }); // 重新构建分页数据以包含转换后的项目 $paginationData = [ 'data' => $transformedData, 'current_page' => $data->currentPage(), 'last_page' => $data->lastPage(), 'per_page' => $data->perPage(), 'total' => $data->total(), 'first_page_url' => $data->url(1), 'last_page_url' => $data->url($data->lastPage()), 'next_page_url' => $data->nextPageUrl(), 'prev_page_url' => $data->previousPageUrl(), 'from' => $data->firstItem(), 'to' => $data->lastItem(), 'path' => $data->path(), 'links' => $data->linkCollection()->toArray(), ]; } else { $paginationData = [ 'data' => $data['data'] ?? $data, 'current_page' => $data['current_page'] ?? 1, 'last_page' => $data['last_page'] ?? 1, 'per_page' => $data['per_page'] ?? 15, 'total' => $data['total'] ?? 0, ]; } return response()->json([ 'success' => true, 'message' => $message, 'timestamp' => now()->toISOString(), ] + $paginationData, $statusCode, [], JSON_UNESCAPED_UNICODE); } ```` ## 安全考虑 - 所有访问令牌都与 IP 地址绑定,防止令牌被盗用 - 使用 Redis 存储令牌,支持自动过期 - 提供令牌刷新机制,减少长期令牌的风险 - 支持登出功能,立即使令牌失效 ## 贡献 欢迎提交 Issue 和 Pull Request 来改进此包。 ## 许可证 MIT License