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

Laravel Sanctum报错:在字符串上调用isPast()方法失败

Laravel Sanctum 调用isPast()报错:Call to a member function isPast() on string

问题场景

刚完成Laravel项目的Sanctum配置,请求/api/user接口验证功能时触发报错,路由代码如下:

Route::post('/login', [AuthController::class, 'login']);

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

报错详情

Error: Call to a member function isPast() on string in file /var/www/TiWake/vendor/laravel/sanctum/src/Guard.php on line 160

#0 /var/www/TiWake/vendor/laravel/sanctum/src/Guard.php(69): Laravel\Sanctum\Guard->isValidAccessToken(Object(App\Models\PersonalAccessToken))
#1 [internal function]: Laravel\Sanctum\Guard->__invoke(Object(Illuminate\Http\Request), NULL)
#2 /var/www/TiWake/vendor/laravel/framework/src/Illuminate/Auth/RequestGuard.php(57): call_user_func(Object(Laravel\Sanctum\Guard), Object(Illuminate\Http\Request), NULL)
#3 /var/www/TiWake/vendor/laravel/framework/src/Illuminate/Auth/GuardHelpers.php(60): Illuminate\Auth\RequestGuard->user()
#4 /var/www/TiWake/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php(63): Illuminate\Auth\RequestGuard->check()
#5 /var/www/TiWake/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php(42): Illuminate\Auth\Middleware\Authenticate->authenticate(Object(Illuminate\Http\Request), Array)

已尝试的操作

自定义PersonalAccessToken模型并添加类型转换,同时在AppServiceProvider中配置使用该模型,但问题依旧:

自定义模型代码:

class PersonalAccessToken extends SanctumPersonalAccessToken
{
    protected $casts = [    
        'abilities' => 'json',
        'last_used_at' => 'datetime',
        'expired_at' => 'datetime',
        '   ' => 'datetime',
    ];
}

AppServiceProvider配置:

public function boot()
{
    Sanctum::usePersonalAccessTokenModel(PersonalAccessToken::class);
}

当前使用版本:

"laravel/framework": "^9.0"
"laravel/sanctum": "^3.2"

问题根源与解决方案

核心问题

报错出现在Guard.php的$accessToken->expires_at->isPast()调用,说明expires_at字段被读取为字符串而非Carbon实例,原因有两个:

  1. 类型转换字段名错误:Sanctum默认过期字段是expires_at,但代码中写的是expired_at(多了一个字母d)
  2. 存在无效的空键' ' => 'datetime',破坏了类型转换配置的有效性

修复步骤

  1. 修正自定义模型的类型转换配置
    将错误的字段名改为正确的expires_at,并移除无效空键:
class PersonalAccessToken extends SanctumPersonalAccessToken
{
    protected $casts = [    
        'abilities' => 'json',
        'last_used_at' => 'datetime',
        'expires_at' => 'datetime',
    ];
}
  1. 清除缓存确保配置生效
    执行命令清除配置和模型缓存:
php artisan config:clear
php artisan model:clear
  1. 检查并修正数据库字段类型
    确认personal_access_tokens表的expires_at字段为timestamp或datetime类型,如果是字符串类型,生成迁移修改:
# 生成迁移文件
php artisan make:migration fix_expires_at_type_in_personal_access_tokens_table

# 在迁移文件中添加修改逻辑
public function up()
{
    Schema::table('personal_access_tokens', function (Blueprint $table) {
        $table->timestamp('expires_at')->nullable()->change();
    });
}

# 执行迁移
php artisan migrate
  1. 重新生成Token
    之前生成的Token可能存储了字符串格式的过期时间,需要重新生成新Token进行测试。

验证修复

携带新生成的Sanctum Token重新请求/api/user接口,此时expires_at会被正确转换为Carbon实例,isPast()方法可正常调用,认证流程恢复正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 18:40:31