API 认证
介绍
默认情况下,Laravel 提供了一种简单的 API 认证解决方案,通过为应用程序的每个用户分配一个随机令牌。在 config/auth.php
配置文件中,已经定义了一个 api
守卫,并使用了 token
驱动。此驱动负责检查传入请求中的 API 令牌,并验证其是否与数据库中用户分配的令牌匹配。
虽然 Laravel 提供了一个简单的基于令牌的认证守卫,但我们强烈建议您考虑使用 Laravel Passport 来为提供 API 认证的生产应用程序提供强大的解决方案。
配置
数据库准备
在使用 token
驱动之前,您需要创建一个迁移,以便在 users
表中添加一个 api_token
列:
Schema::table('users', function ($table) {
$table->string('api_token', 80)->after('password')
->unique()
->nullable()
->default(null);
});
创建迁移后,运行 migrate
Artisan 命令。
如果您选择使用不同的列名,请确保在 config/auth.php
配置文件中更新 API 的 storage_key
配置选项。
生成令牌
一旦 api_token
列被添加到 users
表中,您就可以为每个注册到应用程序的用户分配随机 API 令牌。您应该在用户注册期间为用户创建 User
模型时分配这些令牌。使用 make:auth
Artisan 命令提供的认证脚手架时,可以在 RegisterController
的 create
方法中完成此操作:
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Hash;
/**
* 在有效注册后创建一个新的用户实例。
*
* @param array $data
* @return \App\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'api_token' => Str::random(60),
]);
}
令牌哈希
在上面的示例中,API 令牌以明文形式存储在数据库中。如果您希望使用 SHA-256 哈希对 API 令牌进行哈希,可以将 api
守卫配置的 hash
选项设置为 true
。api
守卫在 config/auth.php
配置文件中定义:
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => true,
],
生成哈希令牌
使用哈希 API 令牌时,您不应在用户注册期间生成 API 令牌。相反,您需要在应用程序中实现自己的 API 令牌管理页面。此页面应允许用户初始化和刷新其 API 令牌。当用户请求初始化或刷新其令牌时,您应在数据库中存储令牌的哈希副本,并将令牌的明文副本返回给视图/前端客户端以供一次性显示。
例如,一个初始化/刷新给定用户令牌并以 JSON 响应返回明文令牌的控制器方法可能如下所示:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
class ApiTokenController extends Controller
{
/**
* 更新认证用户的 API 令牌。
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function update(Request $request)
{
$token = Str::random(60);
$request->user()->forceFill([
'api_token' => hash('sha256', $token),
])->save();
return ['token' => $token];
}
}
由于上面示例中的 API 令牌具有足够的熵,因此创建“彩虹表”来查找哈希令牌的原始值是不切实际的。因此,不需要使用 bcrypt
等慢速哈希方法。
保护路由
Laravel 包含一个认证守卫,它将自动验证传入请求的 API 令牌。您只需在任何需要有效访问令牌的路由上指定 auth:api
中间件:
use Illuminate\Http\Request;
Route::middleware('auth:api')->get('/user', function(Request $request) {
return $request->user();
});
在请求中传递令牌
有几种方法可以将 API 令牌传递给您的应用程序。我们将讨论每种方法,并使用 Guzzle HTTP 库来演示其用法。您可以根据应用程序的需要选择任何一种方法。
查询字符串
您的应用程序的 API 消费者可以将其令牌指定为 api_token
查询字符串值:
$response = $client->request('GET', '/api/user?api_token='.$token);
请求负载
您的应用程序的 API 消费者可以在请求的表单参数中包含其 API 令牌作为 api_token
:
$response = $client->request('POST', '/api/user', [
'headers' => [
'Accept' => 'application/json',
],
'form_params' => [
'api_token' => $token,
],
]);
Bearer 令牌
您的应用程序的 API 消费者可以在请求的 Authorization
头中提供其 API 令牌作为 Bearer
令牌:
$response = $client->request('POST', '/api/user', [
'headers' => [
'Authorization' => 'Bearer '.$token,
'Accept' => 'application/json',
],
]);