文章目录
- 一、前言
- 二、版本约定
- 三、配置实现api-token
- 四、api-token的不足
- 五、推荐使用jwt
- 六、总结
一、前言
用户认证在任何框架内都是很重要的一部分,Laravel为用户认证提供了丰富的实现方式,包括但不仅限于
- session
- token
- jwt
本文将要解决以下问题:
- token的认证方式是如何配置的?
- api-token有什么不足
- 推荐哪个认证方式?
二、版本约定
- Laravel 5.8
- PHP 7.1
三、配置实现api-token
我们实现的token是api-token,最直观描述是,手动设置token值,自动校验token并返回用户表数据。
第一步,配置数据表。对于需要验证的数据表,对应的model要设置继承Authenticatable
。
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
然后,需要在表中增加一列api_token
,建议长度64以上。
第二步,修改config/auth.php
。
Laravel的auth配置可以理解为两层,guards
->providers
。相关的配置如下。
'guards' => [
'api' => [
'driver' => 'token',
'provider' => 'user', //这里是下面的provider的名字
'hash' => false,
],
],
'providers' => [
'user' => [
'driver' => 'eloquent', //这里指向了model,也可以使用datebase直接指向数据表
'model' => App\Models\User::class,
],
],
第三步,业务上更新api_token
。
public function updateTokenByUid($uid){
$token = hash('sha256', random_bytes(32)); //随机生成64位字符串
User::where('id', $uid)->update(['api_token' => $token]);
return $token;
}
第四步,需要验证的控制器配置中间件。
这里我们需要注意的是,需要指定上面配置的guards
的名字是api
的auth。
routes/api.php
Route::resource('/profile', 'ProfileController')->middleware('auth:api');
第五步,获取验证的auth数据。
在配置的控制器内,我们可以通过下面的方式拿到验证的身份。
$user = auth('api')->user();
打印结果是对应数据表的model模型,我们就可以根据需要取出对应的用户数据。
api_token的请求方式支持几种,我们可以根据实际业务选择。
$response = $client->request('GET', '/api/user?api_token='.$token); //get
$response = $client->request('POST', '/api/user', [ //post
'headers' => [
'Accept' => 'application/json',
],
'form_params' => [
'api_token' => $token,
],
]);
$response = $client->request('POST', '/api/user', [ //header
'headers' => [
'Authorization' => 'Bearer '.$token,
'Accept' => 'application/json',
],
]);
有人就要问题,验证不通过怎么处理呢?如果没有通过验证,请求就会经过app/Http/Middleware/Authenticate.php
,我们可以直接给出异常返回。
protected function redirectTo($request)
{
if(! $request->expectsJson()){
ApiReturn::return([],ErrorCode::FORBIDDEN);
exit();
}
}
四、api-token的不足
api-token的验证显然是非常简单的,只需要自己管理用户表的api_token
字段即可。
简单也是有代价的,显而易见的问题有
五、推荐使用jwt
为什么推荐jwt作为接口的验证方式呢?有以下几点。
- jwt可以控制ttl,即token的有效期
- jwt有严谨的结构,Header.Payload.Signature,更加安全
- jwt通过算法分发token,不与数据库结构绑定
六、总结
Laravel通过auth中间件的形式处理中间件,我们可以轻松更换认证方式,使其满足业务需求。
对于接口验证,我更推荐使用jwt。