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年前 自动加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 13

这个扩展性能太差

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 1年前
巴啦啦臭魔仙 (楼主) 1年前

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

1年前 评论
巴啦啦臭魔仙 (楼主) 1年前

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

1年前 评论
巴啦啦臭魔仙 (楼主) 1年前

Up主,如果是移动端api开发呢? 比如小程序,该怎么开发呢?有相关文档分享一下,谢谢,给你点赞

1年前 评论

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