Laravel 11集成MongoDB登录调用createToken报错:Call to a member function prepare() on null
Laravel 11 调用createToken时抛出"Call to a member function prepare() on null"错误
问题描述
在Laravel 11框架中实现登录功能时,Auth::login($member)执行正常,但调用$member->createToken('Personal Access Token')->plainTextToken时,抛出**"Call to a member function prepare() on null"**错误。
相关代码
控制器代码
public function login($request) { $request->validate([ 'email' => 'required|email', 'password' => 'required', ]); $member = Member::where('email', $request->email)->first(); if (!$member || !Hash::check($request->password, $member['password'])) { return response()->ErrorResponse('Email or password is incorrect.'); } Auth::login($member); $token = $member->createToken('Personal Access Token')->plainTextToken; return response()->SuccessResponse($member); }
Member模型代码
namespace App\Models; use MongoDB\Laravel\Eloquent\Model; use Laravel\Sanctum\HasApiTokens; use MongoDB\Laravel\Auth\User as Authenticatable; class Member extends Authenticatable { use HasApiTokens; protected $connection = 'mongodb'; protected $collection = 'Members'; protected $fillable = [ 'userName', 'email', 'status', 'createdDate', 'password' ]; protected $casts = [ 'createdDate' => 'datetime', ]; }
config/auth.php 配置片段
'guards' => [ 'api' => [ 'driver' => 'mongodb', 'provider' => 'members', 'hash' => false, ], ], 'providers' => [ 'members' => [ 'driver' => 'eloquent', 'model' => App\Models\Member::class, ], ],
解决方案
这个错误的核心原因是Laravel Sanctum默认使用SQL数据库存储Token,但项目使用MongoDB作为数据库,导致Token模型的数据库连接不匹配,同时Auth Guard配置也不符合Sanctum的要求。以下是修复步骤:
1. 修正Auth Guard配置
修改config/auth.php中的api guard驱动为sanctum(Sanctum专属的API认证驱动):
'guards' => [ 'api' => [ 'driver' => 'sanctum', 'provider' => 'members', 'hash' => false, ], ],
2. 创建MongoDB兼容的Sanctum Token模型
在app/Models目录下创建PersonalAccessToken.php,继承Sanctum的Token模型并指定MongoDB连接:
namespace App\Models; use Laravel\Sanctum\PersonalAccessToken as SanctumPersonalAccessToken; class PersonalAccessToken extends SanctumPersonalAccessToken { protected $connection = 'mongodb'; protected $collection = 'personal_access_tokens'; }
3. 配置Sanctum使用自定义Token模型
先发布Sanctum配置文件(如果未发布):
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
然后修改config/sanctum.php中的model项,指向刚才创建的自定义模型:
'model' => App\Models\PersonalAccessToken::class,
4. 创建MongoDB的Token集合
生成迁移文件:
php artisan make:migration create_personal_access_tokens_table --create=personal_access_tokens
修改迁移文件为MongoDB兼容的写法:
use Illuminate\Database\Migrations\Migration; use MongoDB\Laravel\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up() { Schema::connection('mongodb')->create('personal_access_tokens', function (Blueprint $table) { $table->id(); $table->morphs('tokenable'); $table->string('name'); $table->string('token', 64)->unique(); $table->text('abilities')->nullable(); $table->timestamp('last_used_at')->nullable(); $table->timestamp('expires_at')->nullable(); $table->timestamps(); }); } public function down() { Schema::connection('mongodb')->dropIfExists('personal_access_tokens'); } };
运行迁移创建集合:
php artisan migrate
5. 验证修复
重新运行登录逻辑,此时createToken方法应该能正常生成MongoDB存储的Token,不再抛出错误。
内容的提问来源于stack exchange,提问作者Jyothi
相关产品推荐
相关产品推荐

