### 概述
> api应用(TP5.1的时候叫模块)主要是为前后端分离项目准备的,可以使用已有的功能进行api接口的快速开发
接口执行流程为:
1. 前端访问`/api/xx/xx`请求接口
2. `ApiBaseController`基类进行初始化(判断登录/鉴权/防止重复提交/token被盗检测等)工作
3. 执行具体`Controller`中的业务逻辑
4. 返回执行的结果
### 接口开发
- 在`/app/api/controller`文件夹下创建相应的控制器,继承`ApiBaseController`类。
- 配置`$loginExcept`变量,把无需登录验证的`url`加入到里面。
- 在具体方法中直接返回`api_success`或`api_error`即可。
### 配置文件
接口配置参数在/app/api/config/api.php文件中,内容如下:
```php
return [
// api跨域设置
'cross_domain' => [
// 是否允许跨域
'allow' => env('api.allow_cross_domain', true),
// header设置
'header' => [
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Methods' => '*',
// 这个地方可以加入更多自定义的header
'Access-Control-Allow-Headers' => 'Content-Type,' . (env('api.token_position') === 'header' ? env('api.token_field') : 'token'),
// 这个地方也可以加入更多的自定义header
'Access-Control-Request-Headers' => 'Origin, Content-Type, Accept, ' . (env('api.token_position') === 'header' ? env('api.token_field') : 'token'),
],
],
// api响应配置
'response' => [
// HTTP状态码和业务状态码同步
'http_code_sync' => env('api.http_code_sync', false),
],
'auth' => [
'jwt_key' => env('api.jwt_key', 'f2244f5316b70ef2887514b65caf795f'),
'jwt_exp' => (int)env('api.jwt_exp', 3600),
'jwt_aud' => env('api.jwt_aud', 'a'),
'jwt_iss' => env('api.jwt_iss', 's'),
'enable_refresh_token' => (bool)env('api.enable_refresh_token', true),
'refresh_token_exp' => (int)env('api.refresh_token_exp', 1296000),
'reuse_check' => (bool)env('api.reuse_check', true),
'token_position' => env('api.token_position', 'header'),
'token_field' => env('api.token_field', 'token'),
]
];
```
### 登录校验
安全校验采用`jwt`进行校验,`jwt`采用extend中自行封装的jwt扩展包,在`/app/api/traits/ApiAuthTrait.php`中封装了相关方法。
#### 登录验证流程
![](https://img.kancloud.cn/66/3a/663a1f35721bff72774e9fb9ef2a816b.svg)
#### jwt配置
> 当自动刷新token的时候,前端保存后端传过来的新token,此后都用新的token进行访问。如果不想使用oken刷新可以把过期时间设置的大一些,例如1年之类的。
~~~
protected $config = [
//token在header中的name
'name' => 'token',
//加密使用的secret
'secret' => '552ac90778a976c72f7f673db174df30',
//颁发者
'iss' => 'iss',
//使用者
'aud' => 'aud',
//过期时间,以秒为单位,默认2小时
'ttl' => 30,
//刷新时间,以秒为单位,默认14天,以
'refresh_ttl' => 1209600,
//是否自动刷新,开启后可自动刷新token,附在header中返回,name为`Authorization`,字段为`Bearer `+$token
'auto_refresh' => true,
//黑名单宽限期,以秒为单位,首次token刷新之后在此时间内原token可以继续访问
'blacklist_grace_period' => 60
];
~~~
### 返回数据
返回数据为json格式,正常情况下会包括`code`,`msg`,`data`字段,分别代表状态码,消息,主数据。
```json
{
"code": 200,
"msg": "success",
"data": {}
}
```
### 返回状态码
> 因 HTTP 状态码多的吓人,所以目前默认采用`200`HTTP态码来控制接口的返回,前端需要判断业务状态可以直接获取返回`body`内的`code`进行判断,如果需要HTTP状态码与业务状态码统一可自行在`.env`中配置。
目前定义的业务状态码有以下几种:
* 200 代表成功。所有的接口成功返回都是200
* 400 表示客户端错误。例如输入的字段类型不匹配等
* 401 未登录/登录状态失效。代表需要客户端发起登录流程
* 403 表示此用户无权限。例如普通用户无法观看vip课程,可直接返回403
* 404 接口不存在。访问了不存在的接口就会返回404
* 500 代表失败。具体原因可参考body内msg字段
其中,我们用的最多的就是`200`和`500`了,401在登录鉴权的地方可以自动返回,一般无需自己处理,`404`系统也自定义好了,无需手动处理,`500`在`/application/common/exception/Http.php`文件中也做了捕获处理。`400`和`403`可酌情使用,不想麻烦的也可以直接用500来代替。
### 开发示例
#### 登录
登录功能可以直接参考`/application/api/controller/AuthController.php`中的`login`方法。
#### 资源控制器
可以直接参考`/application/api/controller/UserController.php`控制器。