如何使用 Laravel Sanctum 处理 SPA 和基于令牌的身份验证
Posted
技术标签:
【中文标题】如何使用 Laravel Sanctum 处理 SPA 和基于令牌的身份验证【英文标题】:How can i handle both SPA and token based authentication with Laravel Sanctum 【发布时间】:2021-09-16 03:20:39 【问题描述】:我花了几天时间在 Laravel Sanctum 上试图弄清楚如何设置我的身份验证系统。
上下文
我正在为我的公司构建一个门票网络应用程序,为此我决定构建一个 API 和一个使用该 API 的 React 前端应用程序。该应用程序的最终用户需要一个帐户来管理工单,因此我在数据库中创建了一个用户表,并为 API 创建了多个路由来创建、删除和更新用户。为了管理用户 api 身份验证,我决定使用 Laravel Sanctum 和他内置的基于会话的 SPA 身份验证系统。
为此,我按照指南设置了所有需求,以确保前端已准备好与 laravel sanctum 一起使用。这是我用于 api 中间件的 Kernel.php:
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
以及 web.php 中通过 Laravel Sanctum SPA 身份验证登录/注销用户的路由。
<?php
use App\Http\Controllers\UserController;
use Illuminate\Support\Facades\Route;
Route::post('/login', [UserController::class, 'login']);
Route::get('/logout', [UserController::class, 'logout']);
问题
我必须构建一个非 Web 应用程序,特别是一个 Windows 服务,它需要在数据库中获取数据并使用 API 的 /api/tickets
端点和 POST
方法来使用这些数据创建一个新票证.
我知道这个 futur windows-service 不是前端应用程序,所以我不能使用 SPA 身份验证系统。相反,我想使用带有 Laravel Sanctum 的令牌来验证服务。
我的问题是:
如何实现这一点并将users
身份验证和
service
身份验证。
因为我的 api 包含 http://myapi.net/login
et
http://myapi.net/logout
用于最终用户身份验证,我需要吗
创建类似api/auth/service
路由来发送和删除令牌?
我应该在我的数据库中创建一个名为service
的新表还是留下来?
与user
表?
【问题讨论】:
【参考方案1】:我正在从事一个具有类似背景的项目。我所做的是根据他们被允许对 API 的使用来建立用户配置文件。为此使用圣所令牌能力: https://laravel.com/docs/8.x/sanctum#token-abilities
-
确保您的 User 类扩展 Authenticable:
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
use HasApiTokens, HasFactory, Notifiable;
-
为您的服务配置文件身份验证创建 API 路由和控制器方法,您可以在其中分配一些您需要的特殊令牌功能:
$token = $user->createToken('app-token', ['service'])->plainTextToken;
...其中“服务”将是您要检查的能力。在 /login 端点中将此令牌作为 API-KEY 返回。
-
在每个服务 API 路径上,使用 Sanctum 中间件验证身份验证:
Route::middleware('auth:sanctum')->post('/updatesomething', 'something@update');
-
在控制器方法中,验证令牌功能以防止 Web 用户使用它们,反之亦然。理想情况下,您可以使用此逻辑创建一个新的中间件以应用于这些路由。
public function update(Request $request)
if ($user->tokenCan('service'))
//do allowed actions to user profile 'service'
通过这种方式,您现在可以使用“服务”配置文件来使用您的 API,并为此使用在以下请求中 /login 中收到的令牌进行身份验证。您应该将其包含在“Bearer Token”之类的标头中。 或者,您可以在 API 中创建注销方法,并在您认为合适时撤销令牌:
$user->tokens()->delete();
【讨论】:
嗨 jssDev!抱歉花了这么长时间才回答,我正在度假,当我回来时,我没想到很快就回来了。所以基本上我理解你的建议,我想我会处理这个。我只有一个问题:我的服务不需要用于身份验证的电子邮件,而用户(最终用户)需要一个,所以我需要为服务创建另一个 Authenticatable 模型对吗? 嗨阿德里安!抱歉耽搁了,但这次是我在度假:) 我认为没有必要创建一个新模型。只需尝试在您的登录控制器方法中唯一地获取用户(可能通过用户 ID)。作为响应,除了身份验证令牌之外,您还必须返回此用户对象。以上是关于如何使用 Laravel Sanctum 处理 SPA 和基于令牌的身份验证的主要内容,如果未能解决你的问题,请参考以下文章
使用 laravel sanctum 在 vue 中保存令牌的最佳方法
如何在没有典型 laravel /login 的情况下使用 laravel sanctum
如何使用 Laravel Sanctum 和 React 修复 401 Unauthorized 错误?
如何选择使用 Laravel Sanctum 进行身份验证?