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实例,原因有两个:
- 类型转换字段名错误:Sanctum默认过期字段是
expires_at,但代码中写的是expired_at(多了一个字母d) - 存在无效的空键
' ' => 'datetime',破坏了类型转换配置的有效性
修复步骤
- 修正自定义模型的类型转换配置
将错误的字段名改为正确的expires_at,并移除无效空键:
class PersonalAccessToken extends SanctumPersonalAccessToken { protected $casts = [ 'abilities' => 'json', 'last_used_at' => 'datetime', 'expires_at' => 'datetime', ]; }
- 清除缓存确保配置生效
执行命令清除配置和模型缓存:
php artisan config:clear php artisan model:clear
- 检查并修正数据库字段类型
确认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
- 重新生成Token
之前生成的Token可能存储了字符串格式的过期时间,需要重新生成新Token进行测试。
验证修复
携带新生成的Sanctum Token重新请求/api/user接口,此时expires_at会被正确转换为Carbon实例,isPast()方法可正常调用,认证流程恢复正常。
内容的提问来源于stack exchange,提问作者Urma
相关产品推荐
相关产品推荐

