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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 01:40:58