Laravel Sanctum 的使用

重写默认模型

由于 laravel 自带的表名叫 personal_access_tokens,开发中我们习惯用户表名叫 users,所以我们可以将表名修改为 user_tokens

1、创建 UserToken 模型文件

php artisan make:model UserToken

模型文件 UserToken.php 内容如下:

<?php

namespace App\Models;

use Laravel\Sanctum\PersonalAccessToken as SanctumPersonalAccessToken;
use DateTimeInterface;

class UserToken extends SanctumPersonalAccessToken
{
    // 转换时间格式
    protected function serializeDate(DateTimeInterface $dateTime): string
    {
        return $dateTime->format('Y-m-d H:i:s');
    }
}

2、设置模型名称

app/Providers/AuthServiceProvider.php 文件中,调用 usePersonalAccessTokenModel 方法设置访问令牌模型名称:

use App\Models\UserToken;
use Laravel\Sanctum\Sanctum;

/**
 * 引导应用程序服务。
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();
    // 设置访问令牌模型名称
    Sanctum::usePersonalAccessTokenModel(UserToken::class);
}

这样重写默认模型就完成了

自定义验证

我们在实际开发中,验证规则可能会需要做一些自定义的操作,所以我们可以通过回调函数来进行自定义验证,里面的就可以写一些我们自定义的逻辑内容:

指定验证访问令牌的回调

app/Providers/AuthServiceProvider.php 文件中,调用 authenticateAccessTokensUsing 方法指定验证访问令牌的回调

use App\Models\UserToken;
use Laravel\Sanctum\Sanctum;

/**
 * 引导应用程序服务。
 *
 * @return void
 */
public function boot()
{
    $this->registerPolicies();
    // 验证访问令牌的回调
    Sanctum::authenticateAccessTokensUsing(
        static function (PersonalAccessToken $accessToken, bool $isValid) {
            // 你的自定义逻辑
        }
    );
}

$accessToken 为 token 信息,tokenable 包含了用户基本信息,token 过期时 tokenable 字段就不会再返回

Laravel Sanctum 自定义访问令牌

$isValid 为 token 有效状态,当 token 未过期时返回 true,否则就返回 false

Laravel Sanctum 自定义访问令牌

自定义令牌有效期

Sanctum 可以在 config/sanctum.php 配置文件中通过 expiration 来设置过期时间,单位为分钟,但无法灵活地设置过期时间

1、设置短期令牌

(1)创建令牌时,对令牌设置令牌能力 server:limited

$user->createToken('token-name', ['server:limited'])->plainTextToken;

(2)在 app/Providers/AuthServiceProvider.php 文件中根据令牌能力设置过期时间:

如果令牌有效,就将 token 过期时间设置为自定义的过期时间,下面 now()->subMinutes(5) 表示有效期为 5 分钟

 public function boot()
 {
     $this->registerPolicies();
     // 验证访问令牌的回调
     Sanctum::authenticateAccessTokensUsing(
         static function (PersonalAccessToken $accessToken, bool $isValid) {
             if (!$accessToken->can('server:limited')) {
                return $isValid;
             }
             return $isValid && $accessToken->created_at->gt(now()->subMinutes(5));
         }
     );
 }

2、设置一次性访问令牌

(1)创建令牌时,对令牌设置令牌能力 server:once

$user->createToken('token-name', ['server:once'])->plainTextToken;

(2)在 app/Providers/AuthServiceProvider.php 文件中根据令牌能力设置过期时间:

如果令牌有效,并且未登陆过,就将 token 设置为失效,即可实现一次性令牌效果

 public function boot()
 {
     $this->registerPolicies();
     // 验证访问令牌的回调
     Sanctum::authenticateAccessTokensUsing(
         static function (PersonalAccessToken $accessToken, bool $isValid) {
             if (!$accessToken->can('server:once')) {
                return $isValid;
             }
             return $isValid && $accessToken->last_used_at ===  null;
         }
     );
 }

如有更好的使用技巧可以在评论留言讨论,如果好用我会更新到文章内

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 1个月前 自动加精
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 12
保安

这个扩展性能太差

2个月前 评论
巴啦啦臭魔仙 (楼主) 2个月前

扩展性能不是很好

2个月前 评论
巴啦啦臭魔仙 (楼主) 2个月前
// 验证访问令牌的回调
Sanctum::authenticateAccessTokensUsing(
    static function (PersonalAccessToken $accessToken, bool $isValid) {
          // 你的自定义逻辑
          dd($accessToken);
       }
);


 #attributes: array:9 [
    "id" => 5
    "tokenable_type" => "App\Models\User"
    "tokenable_id" => 1
    "name" => "1"
    "token" => "23c8f6b3ad9dc564f626caf36fa435679353c47b15ffb071e5fcacdccb5ee705"
    "abilities" => "["*"]"
    "last_used_at" => null
    "created_at" => "2022-04-08 16:07:59"
    "updated_at" => "2022-04-08 16:07:59"
  ]

你好,我这里打印的 $accessToken 信息,好像没有看到 tokenable ,这是怎么回事?

2个月前 评论
巴啦啦臭魔仙 (楼主) 2个月前
pupuchen521 3周前
巴啦啦臭魔仙 (楼主) 3周前

如果 前台用户 一张表 后台用户一张表 ,要怎么弄?

2周前 评论
巴啦啦臭魔仙 (楼主) 2周前

我觉得这些东西 还不如自己写个token放reids 不太好用

6天前 评论
巴啦啦臭魔仙 (楼主) 5天前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!