You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Laravel Sanctum仅校验归属指定模型的Token

结论

该需求完全可以实现,无需修改Sanctum核心代码,用官方提供的扩展能力即可完成。

Sanctum默认的personal_access_tokens表本身就通过tokenable_type做多态关联区分令牌所属模型,你只需要给令牌查询加上固定的类型过滤条件,就能让鉴权流程只识别归属指定模型(比如App\Models\Group)的令牌。

具体实现方案

最稳定的实现方式是自定义PersonalAccessToken模型,通过全局作用域强制加查询条件,步骤如下:

  • 新建自定义的PersonalAccessToken模型,继承Sanctum自带的基类,在启动方法中加全局作用域,限定只查询目标模型的令牌:
<?php

namespace App\Models;

use Laravel\Sanctum\PersonalAccessToken as BaseToken;
use Illuminate\Database\Eloquent\Builder;

class PersonalAccessToken extends BaseToken
{
    protected static function booted()
    {
        static::addGlobalScope('limit_token_owner', function (Builder $query) {
            // 这里替换成你要限定的模型类即可,当前示例为仅识别Group模型的令牌
            $query->where('tokenable_type', \App\Models\Group::class);
        });
    }
}
  • 在服务提供者中注册自定义模型,替换Sanctum默认的模型实现。打开app/Providers/AppServiceProvider.php,在boot方法中加入以下代码:
use Laravel\Sanctum\Sanctum;
use App\Models\PersonalAccessToken;

public function boot()
{
    Sanctum::usePersonalAccessTokenModel(PersonalAccessToken::class);
    // 其他原有启动逻辑保持不变
}

配置完成后,所有Sanctum的鉴权查询都会自动带上tokenable_type的过滤条件,属于App\Models\User的令牌即使明文、哈希值匹配,也会因为查不到对应记录直接鉴权失败,完全符合需求。

如果你的场景是不同路由需要分别校验不同模型的令牌,不需要全局限制,可以选择写一个校验中间件,在Sanctum解析出令牌后额外判断所属模型,不符合就返回401即可,逻辑更灵活。示例中间件核心逻辑:

public function handle($request, Closure $next)
{
    $token = $request->user()?->currentAccessToken();
    if (!$token || $token->tokenable_type !== \App\Models\Group::class) {
        abort(401);
    }
    return $next($request);
}

把这个中间件绑定到对应路由上就能实现局部范围的令牌类型校验。

内容的提问来源于stack exchange,提问作者KordDEM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 13:15:39