refactor: restructure API authentication system and remove legacy files
- Updated API routes to use a unified versioning scheme under `/api/v1/auth`. - Implemented new authentication controller for login, registration, and token management. - Removed legacy user and index controllers, along with associated models and validation files. - Updated documentation to reflect new API endpoints and usage. - Cleaned up unused service and middleware files to streamline the application structure.
This commit is contained in:
@@ -30,29 +30,32 @@ APP_DEBUG = true
|
|||||||
## 2. 路由和访问
|
## 2. 路由和访问
|
||||||
|
|
||||||
### Q: 如何访问 API 接口?
|
### Q: 如何访问 API 接口?
|
||||||
A: URL 格式为 `http://域名/应用名/控制器/方法`
|
A: 当前项目使用固定路由入口,认证接口统一走 `http://域名/api/v1/auth/*`
|
||||||
- 示例:`http://localhost:8000/api/index/index`
|
- 登录:`POST http://localhost:8000/api/v1/auth/login`
|
||||||
- 或使用路由:`http://localhost:8000/api/index`(需配置路由)
|
- 注册:`POST http://localhost:8000/api/v1/auth/register`
|
||||||
|
- 当前用户:`GET http://localhost:8000/api/v1/auth/me`
|
||||||
|
|
||||||
### Q: 如何添加新的路由?
|
### Q: 如何添加新的路由?
|
||||||
A: 在 `route/api.php` 文件中添加路由规则:
|
A: 在 `app/api/route/app.php` 文件中添加路由规则:
|
||||||
```php
|
```php
|
||||||
Route::get('user/profile', 'api.User/profile');
|
use app\api\controller\v1\Auth;
|
||||||
Route::post('user/update', 'api.User/update');
|
|
||||||
|
Route::post('v1/auth/login', [Auth::class, 'login']);
|
||||||
|
Route::post('v1/auth/register', [Auth::class, 'register']);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Q: 如何设置路由参数?
|
### Q: 如何设置路由参数?
|
||||||
A: 使用 `:参数名` 格式:
|
A: 使用 `:参数名` 格式:
|
||||||
```php
|
```php
|
||||||
Route::get('user/:id', 'api.User/detail');
|
Route::get('v1/example/:id', 'v1.Example/detail');
|
||||||
```
|
```
|
||||||
|
|
||||||
## 3. 控制器开发
|
## 3. 控制器开发
|
||||||
|
|
||||||
### Q: 如何创建新的控制器?
|
### Q: 如何创建新的控制器?
|
||||||
A:
|
A:
|
||||||
1. 手动创建:在 `app/api/controller/` 目录下创建 PHP 文件
|
1. 手动创建:在 `app/api/controller/v1/` 目录下创建 PHP 文件
|
||||||
2. 使用命令:`php think make:controller api@Demo`
|
2. 使用命令:`php think make:controller api@v1/Auth`
|
||||||
|
|
||||||
### Q: 如何返回 JSON 数据?
|
### Q: 如何返回 JSON 数据?
|
||||||
A: 使用基础控制器提供的方法:
|
A: 使用基础控制器提供的方法:
|
||||||
@@ -97,7 +100,10 @@ $this->validate($data, [
|
|||||||
|
|
||||||
2. 使用验证器:
|
2. 使用验证器:
|
||||||
```php
|
```php
|
||||||
$this->validate($data, 'app\api\validate\User.register');
|
$this->validate($data, [
|
||||||
|
'username' => 'require|alphaNum',
|
||||||
|
'password' => 'require|length:6,20',
|
||||||
|
]);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Q: 如何自定义验证错误信息?
|
### Q: 如何自定义验证错误信息?
|
||||||
@@ -137,8 +143,8 @@ A:
|
|||||||
1. 全局中间件:在 `app/api/middleware.php` 中注册
|
1. 全局中间件:在 `app/api/middleware.php` 中注册
|
||||||
2. 路由中间件:在路由定义中使用
|
2. 路由中间件:在路由定义中使用
|
||||||
```php
|
```php
|
||||||
Route::group('api', function () {
|
Route::group('v1/auth', function () {
|
||||||
Route::get('user/info', 'api.User/info');
|
Route::get('me', [\app\api\controller\v1\Auth::class, 'me']);
|
||||||
})->middleware(\app\api\middleware\Auth::class);
|
})->middleware(\app\api\middleware\Auth::class);
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -148,27 +154,28 @@ Route::group('api', function () {
|
|||||||
A:
|
A:
|
||||||
```php
|
```php
|
||||||
// 查询单条
|
// 查询单条
|
||||||
$user = \app\api\model\User::find(1);
|
$member = \app\api\model\Member::findByUserid(1);
|
||||||
|
|
||||||
// 查询多条
|
// 查询多条
|
||||||
$users = \app\api\model\User::where('status', 1)->select();
|
$members = \app\api\model\Member::where('disabled', 0)->select();
|
||||||
|
|
||||||
// 新增
|
// 新增
|
||||||
$user = new \app\api\model\User;
|
$member = new \app\api\model\Member;
|
||||||
$user->username = 'test';
|
$member->username = 'test';
|
||||||
$user->save();
|
$member->password = password_hash('123456', PASSWORD_DEFAULT);
|
||||||
|
$member->save();
|
||||||
|
|
||||||
// 或
|
// 或
|
||||||
\app\api\model\User::create([
|
\app\api\model\Member::create([
|
||||||
'username' => 'test',
|
'username' => 'test',
|
||||||
'password' => '123456',
|
'password' => password_hash('123456', PASSWORD_DEFAULT),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 更新
|
// 更新
|
||||||
\app\api\model\User::update(['id' => 1, 'status' => 0]);
|
\app\api\model\Member::update(['userid' => 1, 'disabled' => 1]);
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
\app\api\model\User::destroy(1);
|
\app\api\model\Member::destroy(1);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Q: 如何使用事务?
|
### Q: 如何使用事务?
|
||||||
|
|||||||
+79
-74
@@ -12,24 +12,26 @@
|
|||||||
|
|
||||||
```
|
```
|
||||||
tp/
|
tp/
|
||||||
├── app/ # 应用目录
|
├── app/
|
||||||
│ ├── api/ # API 应用
|
│ └── api/
|
||||||
│ │ ├── controller/ # 控制器
|
│ ├── controller/
|
||||||
│ │ │ ├── BaseController.php # 基础控制器
|
│ │ ├── BaseController.php
|
||||||
│ │ │ ├── Index.php # 首页控制器
|
│ │ └── v1/
|
||||||
│ │ │ └── User.php # 用户控制器
|
│ │ └── Auth.php
|
||||||
│ │ ├── model/ # 模型
|
│ ├── model/
|
||||||
│ │ ├── validate/ # 验证器
|
│ │ └── Member.php
|
||||||
│ │ ├── middleware/ # 中间件
|
│ ├── service/
|
||||||
│ │ │ ├── Auth.php # 认证中间件
|
│ │ └── AuthService.php
|
||||||
│ │ │ └── CrossDomain.php # 跨域中间件
|
│ ├── middleware/
|
||||||
│ │ ├── common/ # 公共类
|
│ │ ├── Auth.php
|
||||||
│ │ │ └── Response.php # 统一响应类
|
│ │ └── CrossDomain.php
|
||||||
│ │ └── AppService.php # 应用服务
|
│ ├── common/
|
||||||
│ └── BaseController.php # 默认基础控制器
|
│ │ ├── Jwt.php
|
||||||
|
│ │ └── Response.php
|
||||||
|
│ ├── middleware.php
|
||||||
|
│ └── route/
|
||||||
|
│ └── app.php
|
||||||
├── config/ # 配置文件
|
├── config/ # 配置文件
|
||||||
├── route/ # 路由
|
|
||||||
│ └── api.php # API 路由配置
|
|
||||||
├── public/ # 公共资源
|
├── public/ # 公共资源
|
||||||
├── runtime/ # 运行时目录
|
├── runtime/ # 运行时目录
|
||||||
├── vendor/ # Composer 依赖
|
├── vendor/ # Composer 依赖
|
||||||
@@ -112,43 +114,10 @@ php think run
|
|||||||
|
|
||||||
## API 接口文档
|
## API 接口文档
|
||||||
|
|
||||||
### 公共接口(无需认证)
|
### 公开接口
|
||||||
|
|
||||||
#### 1. 首页信息
|
#### 1. 用户登录
|
||||||
- **URL**: `/api/index`
|
- **URL**: `/api/v1/auth/login`
|
||||||
- **Method**: GET
|
|
||||||
- **响应示例**:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"code": 200,
|
|
||||||
"msg": "success",
|
|
||||||
"data": {
|
|
||||||
"name": "ThinkPHP API",
|
|
||||||
"version": "8.1.3",
|
|
||||||
"message": "Welcome to ThinkPHP API Application"
|
|
||||||
},
|
|
||||||
"time": 1640000000
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. 健康检查
|
|
||||||
- **URL**: `/api/health`
|
|
||||||
- **Method**: GET
|
|
||||||
- **响应示例**:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"code": 200,
|
|
||||||
"msg": "success",
|
|
||||||
"data": {
|
|
||||||
"status": "ok",
|
|
||||||
"timestamp": "2024-01-01 12:00:00"
|
|
||||||
},
|
|
||||||
"time": 1640000000
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 3. 用户登录
|
|
||||||
- **URL**: `/api/user/login`
|
|
||||||
- **Method**: POST
|
- **Method**: POST
|
||||||
- **参数**:
|
- **参数**:
|
||||||
- `username`: 用户名(必填)
|
- `username`: 用户名(必填)
|
||||||
@@ -159,15 +128,23 @@ php think run
|
|||||||
"code": 200,
|
"code": 200,
|
||||||
"msg": "登录成功",
|
"msg": "登录成功",
|
||||||
"data": {
|
"data": {
|
||||||
"token": "example_token_xxx",
|
"token": "jwt_access_token",
|
||||||
"username": "demo"
|
"refresh_token": "jwt_refresh_token",
|
||||||
|
"expires_in": 604800,
|
||||||
|
"user": {
|
||||||
|
"userid": 1001,
|
||||||
|
"username": "demo",
|
||||||
|
"v_type": 0,
|
||||||
|
"endtime": 0,
|
||||||
|
"formtypeid": 0
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"time": 1640000000
|
"time": 1640000000
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 4. 用户注册
|
#### 2. 用户注册
|
||||||
- **URL**: `/api/user/register`
|
- **URL**: `/api/v1/auth/register`
|
||||||
- **Method**: POST
|
- **Method**: POST
|
||||||
- **参数**:
|
- **参数**:
|
||||||
- `username`: 用户名(3-20位)
|
- `username`: 用户名(3-20位)
|
||||||
@@ -179,16 +156,31 @@ php think run
|
|||||||
"code": 200,
|
"code": 200,
|
||||||
"msg": "注册成功",
|
"msg": "注册成功",
|
||||||
"data": {
|
"data": {
|
||||||
"user_id": 1001
|
"token": "jwt_access_token",
|
||||||
|
"refresh_token": "jwt_refresh_token",
|
||||||
|
"expires_in": 604800,
|
||||||
|
"user": {
|
||||||
|
"userid": 1001,
|
||||||
|
"username": "demo",
|
||||||
|
"v_type": 0,
|
||||||
|
"endtime": 0,
|
||||||
|
"formtypeid": 0
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"time": 1640000000
|
"time": 1640000000
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### 3. 刷新 Token
|
||||||
|
- **URL**: `/api/v1/auth/refresh`
|
||||||
|
- **Method**: POST
|
||||||
|
- **参数**:
|
||||||
|
- `refresh_token`: 刷新令牌
|
||||||
|
|
||||||
### 认证接口(需要 token)
|
### 认证接口(需要 token)
|
||||||
|
|
||||||
#### 5. 获取用户信息
|
#### 4. 获取用户信息
|
||||||
- **URL**: `/api/user/info`
|
- **URL**: `/api/v1/auth/me`
|
||||||
- **Method**: GET
|
- **Method**: GET
|
||||||
- **Headers**: `token: your_token`
|
- **Headers**: `token: your_token`
|
||||||
- **响应示例**:
|
- **响应示例**:
|
||||||
@@ -197,22 +189,41 @@ php think run
|
|||||||
"code": 200,
|
"code": 200,
|
||||||
"msg": "success",
|
"msg": "success",
|
||||||
"data": {
|
"data": {
|
||||||
"id": 1,
|
"userid": 1,
|
||||||
"username": "demo_user",
|
"username": "demo_user",
|
||||||
"nickname": "演示用户",
|
"v_type": 1,
|
||||||
"avatar": "",
|
"endtime": 1777777777,
|
||||||
"email": "demo@example.com",
|
"formtypeid": 0,
|
||||||
"created_at": "2024-01-01 12:00:00"
|
"disabled": 0,
|
||||||
|
"product": {
|
||||||
|
"v_type": 1,
|
||||||
|
"video_num": 100,
|
||||||
|
"account_num": 5
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"time": 1640000000
|
"time": 1640000000
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### 5. 退出登录
|
||||||
|
- **URL**: `/api/v1/auth/logout`
|
||||||
|
- **Method**: POST
|
||||||
|
- **Headers**: `token: your_token`
|
||||||
|
|
||||||
|
#### 6. 修改密码
|
||||||
|
- **URL**: `/api/v1/auth/password`
|
||||||
|
- **Method**: POST
|
||||||
|
- **Headers**: `token: your_token`
|
||||||
|
- **参数**:
|
||||||
|
- `old_password`: 原密码
|
||||||
|
- `new_password`: 新密码
|
||||||
|
- `confirm_password`: 确认新密码
|
||||||
|
|
||||||
## 功能特性
|
## 功能特性
|
||||||
|
|
||||||
### 1. 多应用模式
|
### 1. 多应用模式
|
||||||
- 采用 ThinkPHP 多应用扩展
|
- 采用 ThinkPHP 多应用扩展
|
||||||
- API 接口独立目录
|
- API 接口集中在 `app/api`
|
||||||
- 便于扩展其他应用模块
|
- 便于扩展其他应用模块
|
||||||
|
|
||||||
### 2. 统一响应格式
|
### 2. 统一响应格式
|
||||||
@@ -238,9 +249,6 @@ $this->validate($data, [
|
|||||||
'username' => 'require|length:3,20',
|
'username' => 'require|length:3,20',
|
||||||
'password' => 'require|length:6,20',
|
'password' => 'require|length:6,20',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 或使用验证器
|
|
||||||
$this->validate($data, 'app\api\validate\User.login');
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5. 模型自动时间戳
|
### 5. 模型自动时间戳
|
||||||
@@ -287,13 +295,10 @@ php think run
|
|||||||
php think clear
|
php think clear
|
||||||
|
|
||||||
# 生成控制器
|
# 生成控制器
|
||||||
php think make:controller api@Demo
|
php think make:controller api@v1/Auth
|
||||||
|
|
||||||
# 生成模型
|
# 生成模型
|
||||||
php think make:model api@Demo
|
php think make:model api@Member
|
||||||
|
|
||||||
# 生成验证器
|
|
||||||
php think make:validate api@Demo
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 扩展安装
|
## 扩展安装
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare (strict_types = 1);
|
|
||||||
|
|
||||||
namespace app;
|
|
||||||
|
|
||||||
use think\Service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 应用服务类
|
|
||||||
*/
|
|
||||||
class AppService extends Service
|
|
||||||
{
|
|
||||||
public function register()
|
|
||||||
{
|
|
||||||
// 服务注册
|
|
||||||
}
|
|
||||||
|
|
||||||
public function boot()
|
|
||||||
{
|
|
||||||
// 服务启动
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare (strict_types = 1);
|
|
||||||
|
|
||||||
namespace app;
|
|
||||||
|
|
||||||
use think\App;
|
|
||||||
use think\exception\ValidateException;
|
|
||||||
use think\Validate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 控制器基础类
|
|
||||||
*/
|
|
||||||
abstract class BaseController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Request实例
|
|
||||||
* @var \think\Request
|
|
||||||
*/
|
|
||||||
protected $request;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 应用实例
|
|
||||||
* @var \think\App
|
|
||||||
*/
|
|
||||||
protected $app;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否批量验证
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
protected $batchValidate = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 控制器中间件
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $middleware = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造方法
|
|
||||||
* @access public
|
|
||||||
* @param App $app 应用对象
|
|
||||||
*/
|
|
||||||
public function __construct(App $app)
|
|
||||||
{
|
|
||||||
$this->app = $app;
|
|
||||||
$this->request = $this->app->request;
|
|
||||||
|
|
||||||
// 控制器初始化
|
|
||||||
$this->initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化
|
|
||||||
protected function initialize()
|
|
||||||
{}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证数据
|
|
||||||
* @access protected
|
|
||||||
* @param array $data 数据
|
|
||||||
* @param string|array $validate 验证器名或者验证规则数组
|
|
||||||
* @param array $message 提示信息
|
|
||||||
* @param bool $batch 是否批量验证
|
|
||||||
* @return array|string|true
|
|
||||||
* @throws ValidateException
|
|
||||||
*/
|
|
||||||
protected function validate(array $data, string|array $validate, array $message = [], bool $batch = false)
|
|
||||||
{
|
|
||||||
if (is_array($validate)) {
|
|
||||||
$v = new Validate();
|
|
||||||
$v->rule($validate);
|
|
||||||
} else {
|
|
||||||
if (strpos($validate, '.')) {
|
|
||||||
// 支持场景
|
|
||||||
[$validate, $scene] = explode('.', $validate);
|
|
||||||
}
|
|
||||||
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
|
|
||||||
$v = new $class();
|
|
||||||
if (!empty($scene)) {
|
|
||||||
$v->scene($scene);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$v->message($message);
|
|
||||||
|
|
||||||
// 是否批量验证
|
|
||||||
if ($batch || $this->batchValidate) {
|
|
||||||
$v->batch(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $v->failException(true)->check($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace app;
|
|
||||||
|
|
||||||
use think\db\exception\DataNotFoundException;
|
|
||||||
use think\db\exception\ModelNotFoundException;
|
|
||||||
use think\exception\Handle;
|
|
||||||
use think\exception\HttpException;
|
|
||||||
use think\exception\HttpResponseException;
|
|
||||||
use think\exception\ValidateException;
|
|
||||||
use think\Response;
|
|
||||||
use Throwable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 应用异常处理类
|
|
||||||
*/
|
|
||||||
class ExceptionHandle extends Handle
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 不需要记录信息(日志)的异常类列表
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $ignoreReport = [
|
|
||||||
HttpException::class,
|
|
||||||
HttpResponseException::class,
|
|
||||||
ModelNotFoundException::class,
|
|
||||||
DataNotFoundException::class,
|
|
||||||
ValidateException::class,
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 记录异常信息(包括日志或者其它方式记录)
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param Throwable $exception
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function report(Throwable $exception): void
|
|
||||||
{
|
|
||||||
// 使用内置的方式记录异常日志
|
|
||||||
parent::report($exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render an exception into an HTTP response.
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param \think\Request $request
|
|
||||||
* @param Throwable $e
|
|
||||||
* @return Response
|
|
||||||
*/
|
|
||||||
public function render($request, Throwable $e): Response
|
|
||||||
{
|
|
||||||
// 添加自定义异常处理机制
|
|
||||||
|
|
||||||
// 其他错误交给系统处理
|
|
||||||
return parent::render($request, $e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace app;
|
|
||||||
|
|
||||||
// 应用请求对象类
|
|
||||||
class Request extends \think\Request
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare (strict_types = 1);
|
|
||||||
|
|
||||||
namespace app\api;
|
|
||||||
|
|
||||||
use think\Service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API 应用服务
|
|
||||||
*/
|
|
||||||
class AppService extends Service
|
|
||||||
{
|
|
||||||
public function register()
|
|
||||||
{
|
|
||||||
// 注册服务
|
|
||||||
}
|
|
||||||
|
|
||||||
public function boot()
|
|
||||||
{
|
|
||||||
// 启动服务
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare (strict_types = 1);
|
|
||||||
|
|
||||||
namespace app\api\controller;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API 示例控制器
|
|
||||||
*/
|
|
||||||
class Index extends BaseController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 首页接口
|
|
||||||
* @return \think\response\Json
|
|
||||||
*/
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
$data = [
|
|
||||||
'name' => 'ThinkPHP API',
|
|
||||||
'version' => app()->version(),
|
|
||||||
'message' => 'Welcome to ThinkPHP API Application',
|
|
||||||
];
|
|
||||||
|
|
||||||
return $this->success($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 健康检查接口
|
|
||||||
* @return \think\response\Json
|
|
||||||
*/
|
|
||||||
public function health()
|
|
||||||
{
|
|
||||||
return $this->success([
|
|
||||||
'status' => 'ok',
|
|
||||||
'timestamp' => date('Y-m-d H:i:s'),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare (strict_types = 1);
|
|
||||||
|
|
||||||
namespace app\api\controller;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户控制器示例
|
|
||||||
*/
|
|
||||||
class User extends BaseController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 用户登录
|
|
||||||
* @return \think\response\Json
|
|
||||||
*/
|
|
||||||
public function login()
|
|
||||||
{
|
|
||||||
$data = $this->request->post();
|
|
||||||
|
|
||||||
// 验证数据
|
|
||||||
$this->validate($data, [
|
|
||||||
'username' => 'require',
|
|
||||||
'password' => 'require',
|
|
||||||
], [
|
|
||||||
'username.require' => '用户名不能为空',
|
|
||||||
'password.require' => '密码不能为空',
|
|
||||||
]);
|
|
||||||
|
|
||||||
// TODO: 实际的登录逻辑
|
|
||||||
return $this->success([
|
|
||||||
'token' => 'example_token_' . md5($data['username']),
|
|
||||||
'username' => $data['username'],
|
|
||||||
], '登录成功');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取用户信息
|
|
||||||
* @return \think\response\Json
|
|
||||||
*/
|
|
||||||
public function info()
|
|
||||||
{
|
|
||||||
// TODO: 从 token 或 session 中获取用户信息
|
|
||||||
$userInfo = [
|
|
||||||
'id' => 1,
|
|
||||||
'username' => 'demo_user',
|
|
||||||
'nickname' => '演示用户',
|
|
||||||
'avatar' => '',
|
|
||||||
'email' => 'demo@example.com',
|
|
||||||
'created_at' => date('Y-m-d H:i:s'),
|
|
||||||
];
|
|
||||||
|
|
||||||
return $this->success($userInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户注册
|
|
||||||
* @return \think\response\Json
|
|
||||||
*/
|
|
||||||
public function register()
|
|
||||||
{
|
|
||||||
$data = $this->request->post();
|
|
||||||
|
|
||||||
// 验证数据
|
|
||||||
$this->validate($data, [
|
|
||||||
'username' => 'require|length:3,20',
|
|
||||||
'password' => 'require|length:6,20',
|
|
||||||
'email' => 'require|email',
|
|
||||||
], [
|
|
||||||
'username.require' => '用户名不能为空',
|
|
||||||
'username.length' => '用户名长度3-20位',
|
|
||||||
'password.require' => '密码不能为空',
|
|
||||||
'password.length' => '密码长度6-20位',
|
|
||||||
'email.require' => '邮箱不能为空',
|
|
||||||
'email.email' => '邮箱格式不正确',
|
|
||||||
]);
|
|
||||||
|
|
||||||
// TODO: 实际的注册逻辑
|
|
||||||
return $this->success([
|
|
||||||
'user_id' => rand(1000, 9999),
|
|
||||||
], '注册成功');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +1,43 @@
|
|||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\api\controller;
|
namespace app\api\controller\v1;
|
||||||
|
|
||||||
use app\api\common\Jwt;
|
|
||||||
use app\api\common\Response;
|
use app\api\common\Response;
|
||||||
use app\api\controller\BaseController;
|
use app\api\controller\BaseController;
|
||||||
use app\api\service\AuthService;
|
use app\api\service\AuthService;
|
||||||
|
use think\App;
|
||||||
use think\exception\ValidateException;
|
use think\exception\ValidateException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 认证控制器 (v1版本)
|
* v1 认证控制器
|
||||||
* 处理用户登录、注册、Token 刷新等
|
|
||||||
*/
|
*/
|
||||||
class Auth extends BaseController
|
class Auth extends BaseController
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var AuthService
|
|
||||||
*/
|
|
||||||
protected AuthService $authService;
|
protected AuthService $authService;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct(App $app)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct($app);
|
||||||
$this->authService = new AuthService();
|
$this->authService = new AuthService();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户登录
|
* 用户登录
|
||||||
* POST /api/v1/auth/login
|
* POST /api/v1/auth/login
|
||||||
* @return \think\response\Json
|
|
||||||
*/
|
*/
|
||||||
public function login()
|
public function login()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$data = $this->request->post();
|
$data = $this->request->post();
|
||||||
|
|
||||||
// 验证参数
|
validate([
|
||||||
validate($data, [
|
|
||||||
'username' => 'require',
|
'username' => 'require',
|
||||||
'password' => 'require',
|
'password' => 'require',
|
||||||
], [
|
], [
|
||||||
'username.require' => '用户名不能为空',
|
'username.require' => '用户名不能为空',
|
||||||
'password.require' => '密码不能为空',
|
'password.require' => '密码不能为空',
|
||||||
]);
|
])->check($data);
|
||||||
|
|
||||||
$result = $this->authService->login(
|
$result = $this->authService->login(
|
||||||
$data['username'],
|
$data['username'],
|
||||||
@@ -61,15 +55,13 @@ class Auth extends BaseController
|
|||||||
/**
|
/**
|
||||||
* 用户注册
|
* 用户注册
|
||||||
* POST /api/v1/auth/register
|
* POST /api/v1/auth/register
|
||||||
* @return \think\response\Json
|
|
||||||
*/
|
*/
|
||||||
public function register()
|
public function register()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$data = $this->request->post();
|
$data = $this->request->post();
|
||||||
|
|
||||||
// 验证参数
|
validate([
|
||||||
validate($data, [
|
|
||||||
'username' => 'require|length:3,20|alphaNum',
|
'username' => 'require|length:3,20|alphaNum',
|
||||||
'password' => 'require|length:6,20',
|
'password' => 'require|length:6,20',
|
||||||
'email' => 'email',
|
'email' => 'email',
|
||||||
@@ -80,7 +72,7 @@ class Auth extends BaseController
|
|||||||
'password.require' => '密码不能为空',
|
'password.require' => '密码不能为空',
|
||||||
'password.length' => '密码长度6-20位',
|
'password.length' => '密码长度6-20位',
|
||||||
'email.email' => '邮箱格式不正确',
|
'email.email' => '邮箱格式不正确',
|
||||||
]);
|
])->check($data);
|
||||||
|
|
||||||
$result = $this->authService->register(
|
$result = $this->authService->register(
|
||||||
$data['username'],
|
$data['username'],
|
||||||
@@ -100,7 +92,6 @@ class Auth extends BaseController
|
|||||||
/**
|
/**
|
||||||
* 刷新 Token
|
* 刷新 Token
|
||||||
* POST /api/v1/auth/refresh
|
* POST /api/v1/auth/refresh
|
||||||
* @return \think\response\Json
|
|
||||||
*/
|
*/
|
||||||
public function refresh()
|
public function refresh()
|
||||||
{
|
{
|
||||||
@@ -122,7 +113,6 @@ class Auth extends BaseController
|
|||||||
/**
|
/**
|
||||||
* 获取当前用户信息
|
* 获取当前用户信息
|
||||||
* GET /api/v1/auth/me
|
* GET /api/v1/auth/me
|
||||||
* @return \think\response\Json
|
|
||||||
*/
|
*/
|
||||||
public function me()
|
public function me()
|
||||||
{
|
{
|
||||||
@@ -143,19 +133,15 @@ class Auth extends BaseController
|
|||||||
/**
|
/**
|
||||||
* 退出登录
|
* 退出登录
|
||||||
* POST /api/v1/auth/logout
|
* POST /api/v1/auth/logout
|
||||||
* @return \think\response\Json
|
|
||||||
*/
|
*/
|
||||||
public function logout()
|
public function logout()
|
||||||
{
|
{
|
||||||
// JWT 无状态,退出只需客户端删除 Token
|
|
||||||
// 如果需要服务端失效,可以将 Token 加入黑名单(需要 Redis 支持)
|
|
||||||
return Response::success([], '退出成功');
|
return Response::success([], '退出成功');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改密码
|
* 修改密码
|
||||||
* POST /api/v1/auth/password
|
* POST /api/v1/auth/password
|
||||||
* @return \think\response\Json
|
|
||||||
*/
|
*/
|
||||||
public function password()
|
public function password()
|
||||||
{
|
{
|
||||||
@@ -167,7 +153,7 @@ class Auth extends BaseController
|
|||||||
|
|
||||||
$data = $this->request->post();
|
$data = $this->request->post();
|
||||||
|
|
||||||
validate($data, [
|
validate([
|
||||||
'old_password' => 'require',
|
'old_password' => 'require',
|
||||||
'new_password' => 'require|length:6,20|confirm:confirm_password',
|
'new_password' => 'require|length:6,20|confirm:confirm_password',
|
||||||
], [
|
], [
|
||||||
@@ -175,7 +161,7 @@ class Auth extends BaseController
|
|||||||
'new_password.require' => '新密码不能为空',
|
'new_password.require' => '新密码不能为空',
|
||||||
'new_password.length' => '新密码长度6-20位',
|
'new_password.length' => '新密码长度6-20位',
|
||||||
'new_password.confirm' => '两次密码输入不一致',
|
'new_password.confirm' => '两次密码输入不一致',
|
||||||
]);
|
])->check($data);
|
||||||
|
|
||||||
$this->authService->changePassword(
|
$this->authService->changePassword(
|
||||||
$payload['userid'],
|
$payload['userid'],
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare (strict_types = 1);
|
|
||||||
|
|
||||||
namespace app\api\model;
|
|
||||||
|
|
||||||
use think\Model;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户模型
|
|
||||||
*/
|
|
||||||
class User extends Model
|
|
||||||
{
|
|
||||||
// 表名
|
|
||||||
protected $name = 'user';
|
|
||||||
|
|
||||||
// 自动写入时间戳
|
|
||||||
protected $autoWriteTimestamp = true;
|
|
||||||
|
|
||||||
// 类型转换
|
|
||||||
protected $type = [
|
|
||||||
'id' => 'integer',
|
|
||||||
'status' => 'integer',
|
|
||||||
];
|
|
||||||
|
|
||||||
// 隐藏字段
|
|
||||||
protected $hidden = ['password', 'delete_time'];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 密码加密
|
|
||||||
* @param string $value
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function setPasswordAttr(string $value): string
|
|
||||||
{
|
|
||||||
return password_hash($value, PASSWORD_DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证密码
|
|
||||||
* @param string $password 明文密码
|
|
||||||
* @param string $hash 加密后的密码
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function verifyPassword(string $password, string $hash): bool
|
|
||||||
{
|
|
||||||
return password_verify($password, $hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+9
-24
@@ -2,35 +2,20 @@
|
|||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
use think\facade\Route;
|
use think\facade\Route;
|
||||||
use app\api\controller\Index;
|
use app\api\controller\v1\Auth;
|
||||||
use app\api\controller\User;
|
|
||||||
use app\api\controller\V1Auth;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API 应用路由
|
* API 应用路由
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// ==================== v1 版本接口 ====================
|
// v1 认证接口(公开)
|
||||||
|
Route::post('v1/auth/login', [Auth::class, 'login']);
|
||||||
|
Route::post('v1/auth/register', [Auth::class, 'register']);
|
||||||
|
Route::post('v1/auth/refresh', [Auth::class, 'refresh']);
|
||||||
|
|
||||||
// 健康检查 (公开)
|
// v1 认证接口(需登录)
|
||||||
Route::get('v1/health', [Index::class, 'health']);
|
|
||||||
|
|
||||||
// 认证接口 (公开)
|
|
||||||
Route::post('v1/auth/login', [V1Auth::class, 'login']);
|
|
||||||
Route::post('v1/auth/register', [V1Auth::class, 'register']);
|
|
||||||
Route::post('v1/auth/refresh', [V1Auth::class, 'refresh']);
|
|
||||||
|
|
||||||
// 认证接口 (需登录)
|
|
||||||
Route::group('v1/auth', function () {
|
Route::group('v1/auth', function () {
|
||||||
Route::get('me', [V1Auth::class, 'me']);
|
Route::get('me', [Auth::class, 'me']);
|
||||||
Route::post('logout', [V1Auth::class, 'logout']);
|
Route::post('logout', [Auth::class, 'logout']);
|
||||||
Route::post('password', [V1Auth::class, 'password']);
|
Route::post('password', [Auth::class, 'password']);
|
||||||
})->middleware(\app\api\middleware\Auth::class);
|
})->middleware(\app\api\middleware\Auth::class);
|
||||||
|
|
||||||
// ==================== 兼容旧版路由 ====================
|
|
||||||
|
|
||||||
Route::get('index', [Index::class, 'index']);
|
|
||||||
Route::get('health', [Index::class, 'health']);
|
|
||||||
Route::post('user/login', [V1Auth::class, 'login']);
|
|
||||||
Route::post('user/register', [V1Auth::class, 'register']);
|
|
||||||
Route::get('user/info', [V1Auth::class, 'me'])->middleware(\app\api\middleware\Auth::class);
|
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare (strict_types = 1);
|
|
||||||
|
|
||||||
namespace app\api\validate;
|
|
||||||
|
|
||||||
use think\Validate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户验证器
|
|
||||||
*/
|
|
||||||
class User extends Validate
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 验证规则
|
|
||||||
*/
|
|
||||||
protected $rule = [
|
|
||||||
'username' => 'require|length:3,20|chsDash',
|
|
||||||
'password' => 'require|length:6,20',
|
|
||||||
'email' => 'require|email',
|
|
||||||
'phone' => 'mobile',
|
|
||||||
'nickname' => 'length:2,20',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证提示信息
|
|
||||||
*/
|
|
||||||
protected $message = [
|
|
||||||
'username.require' => '用户名不能为空',
|
|
||||||
'username.length' => '用户名长度3-20位',
|
|
||||||
'username.chsDash' => '用户名只能是汉字、字母、数字和下划线_及破折号-',
|
|
||||||
'password.require' => '密码不能为空',
|
|
||||||
'password.length' => '密码长度6-20位',
|
|
||||||
'email.require' => '邮箱不能为空',
|
|
||||||
'email.email' => '邮箱格式不正确',
|
|
||||||
'phone.mobile' => '手机号格式不正确',
|
|
||||||
'nickname.length' => '昵称长度2-20位',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证场景
|
|
||||||
*/
|
|
||||||
protected $scene = [
|
|
||||||
'login' => ['username', 'password'],
|
|
||||||
'register' => ['username', 'password', 'email'],
|
|
||||||
'update' => ['email', 'phone', 'nickname'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
<?php
|
|
||||||
// 应用公共文件
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace app\controller;
|
|
||||||
|
|
||||||
use app\BaseController;
|
|
||||||
|
|
||||||
class Index extends BaseController
|
|
||||||
{
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
return '<style>*{ padding: 0; margin: 0; }</style><iframe src="https://www.thinkphp.cn/welcome?version=' . \think\facade\App::version() . '" width="100%" height="100%" frameborder="0" scrolling="auto"></iframe>';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function hello($name = 'ThinkPHP8')
|
|
||||||
{
|
|
||||||
return 'hello,' . $name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
// 事件定义文件
|
|
||||||
return [
|
|
||||||
'bind' => [
|
|
||||||
],
|
|
||||||
|
|
||||||
'listen' => [
|
|
||||||
'AppInit' => [],
|
|
||||||
'HttpRun' => [],
|
|
||||||
'HttpEnd' => [],
|
|
||||||
'LogLevel' => [],
|
|
||||||
'LogWrite' => [],
|
|
||||||
],
|
|
||||||
|
|
||||||
'subscribe' => [
|
|
||||||
],
|
|
||||||
];
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
// 全局中间件定义文件
|
|
||||||
return [
|
|
||||||
// 全局请求缓存
|
|
||||||
// \think\middleware\CheckRequestCache::class,
|
|
||||||
// 多语言加载
|
|
||||||
// \think\middleware\LoadLangPack::class,
|
|
||||||
// Session初始化
|
|
||||||
// \think\middleware\SessionInit::class
|
|
||||||
];
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
use app\ExceptionHandle;
|
|
||||||
use app\Request;
|
|
||||||
|
|
||||||
// 容器Provider定义文件
|
|
||||||
return [
|
|
||||||
'think\Request' => Request::class,
|
|
||||||
'think\exception\Handle' => ExceptionHandle::class,
|
|
||||||
];
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use app\AppService;
|
|
||||||
|
|
||||||
// 系统服务定义文件
|
|
||||||
// 服务在完成全局初始化之后执行
|
|
||||||
return [
|
|
||||||
AppService::class,
|
|
||||||
];
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
use think\facade\Route;
|
|
||||||
use app\api\controller\Index;
|
|
||||||
use app\api\controller\User;
|
|
||||||
use app\api\controller\V1Auth;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API 路由配置
|
|
||||||
*/
|
|
||||||
|
|
||||||
// ==================== v1 版本接口 ====================
|
|
||||||
|
|
||||||
// 健康检查 (公开)
|
|
||||||
Route::get('api/v1/health', [Index::class, 'health']);
|
|
||||||
|
|
||||||
// 认证接口 (公开)
|
|
||||||
Route::post('api/v1/auth/login', [V1Auth::class, 'login']);
|
|
||||||
Route::post('api/v1/auth/register', [V1Auth::class, 'register']);
|
|
||||||
Route::post('api/v1/auth/refresh', [V1Auth::class, 'refresh']);
|
|
||||||
|
|
||||||
// 认证接口 (需登录)
|
|
||||||
Route::group('api/v1/auth', function () {
|
|
||||||
Route::get('me', [V1Auth::class, 'me']);
|
|
||||||
Route::post('logout', [V1Auth::class, 'logout']);
|
|
||||||
Route::post('password', [V1Auth::class, 'password']);
|
|
||||||
})->middleware(\app\api\middleware\Auth::class);
|
|
||||||
|
|
||||||
// ==================== 兼容旧版路由 ====================
|
|
||||||
|
|
||||||
Route::get('api/index', [Index::class, 'index']);
|
|
||||||
Route::get('api/health', [Index::class, 'health']);
|
|
||||||
Route::post('api/user/login', [V1Auth::class, 'login']);
|
|
||||||
Route::post('api/user/register', [V1Auth::class, 'register']);
|
|
||||||
Route::get('api/user/info', [V1Auth::class, 'me'])->middleware(\app\api\middleware\Auth::class);
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
// | Author: liu21st <liu21st@gmail.com>
|
|
||||||
// +----------------------------------------------------------------------
|
|
||||||
use think\facade\Route;
|
|
||||||
|
|
||||||
Route::get('think', function () {
|
|
||||||
return 'hello,ThinkPHP8!';
|
|
||||||
});
|
|
||||||
|
|
||||||
Route::get('hello/:name', 'index/hello');
|
|
||||||
+3
-2
@@ -26,8 +26,9 @@ echo "2. 启动开发服务器:"
|
|||||||
echo " php think run"
|
echo " php think run"
|
||||||
echo ""
|
echo ""
|
||||||
echo "3. 访问测试接口:"
|
echo "3. 访问测试接口:"
|
||||||
echo " - 首页: http://localhost:8000/api/index"
|
echo " - 登录: POST http://localhost:8000/api/v1/auth/login"
|
||||||
echo " - 健康检查: http://localhost:8000/api/health"
|
echo " - 注册: POST http://localhost:8000/api/v1/auth/register"
|
||||||
|
echo " - 刷新 Token: POST http://localhost:8000/api/v1/auth/refresh"
|
||||||
echo ""
|
echo ""
|
||||||
echo "4. 查看完整文档:"
|
echo "4. 查看完整文档:"
|
||||||
echo " cat README_API.md"
|
echo " cat README_API.md"
|
||||||
|
|||||||
Reference in New Issue
Block a user