Laravel Sanctum 的使用

巴啦啦臭魔仙發表於2022-04-08

重寫預設模型

由於 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 協議》,轉載必須註明作者和本文連結

相關文章