I have a laravel 10 application using a mongoDB database, i am creating an API end point to generate token for users in collection api_users. the following function for creating users works perfectly
public function createApiUser(Request $request)
{
// try {
// DB::connection('mongodb')->getPdo(); ### this also is successful when enabled
// return ["Connected successfully to the database!"];
// } catch (\Exception $e) {
// die("Could not connect to the database: " . $e->getMessage());
// }
$username = $request->input('username');
$password = $request->input('password');
$password = Hash::make($password);
$apiUser = new ApiUser();
$apiUser->username = $username;
$apiUser->password = $password;
try {
$apiUser->save();
return ["Success"];
} catch (\Throwable $th) {
//throw $th;
return ["error" => $th->getMessage()];
}
}
but when i make a request to generate token using this function
public function generateToken(Request $request)
{
$username = $request->input('username');
$password = $request->input('password');
$collection = DB::connection('mongodb')->collection('api_users');
// Retrieve the user document based on the username
$userData = ApiUser::where('username', $username)->first();
// return $userData; ###this also returns user details successfully when enabled
if ($userData && Hash::check($password, $userData['password'])) {
// Create an instance of ApiUser model from the retrieved data
$user = $userData;
// return $user;
// Authentication successful, generate a token for the user
$token = $user->createToken('MyApp')->plainTextToken; // **####the error is generated then this line is being executed**
// Return the token to the user as a response
return response()->json([
'token' => $token,
'user' => $user,
], 200);
}
// Authentication failed, return an error response
return response()->json(['error' => 'Unauthorised'], 401);
}
this is the error message
Error: Call to a member function prepare() on null in file /vendor/laravel/framework/src/Illuminate/Database/Connection.php on line 574
and here is the model for ApiUser
<?php
namespace App\Models;
// use MongoDB\Laravel\Eloquent\Model as Eloquent;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use MongoDB\Laravel\Eloquent\Model as Eloquent;
use MongoDB\Laravel\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Model;
use Laravel\Sanctum\HasApiTokens;
// use Illuminate\Foundation\Auth\User as Authenticatable;
// class ApiUser extends Eloquent implements Authenticatable
class ApiUser extends Eloquent
{
use HasApiTokens, HasFactory,Notifiable;
protected $guard = 'api';
protected $table = 'api_users'; // Ensure this matches your MongoDB collection name
protected $connection = 'mongodb'; // Use your MongoDB connection name here
protected $guarded = [];
protected $fillable = [
'username', 'password',
];
}
and the auth.php guard and providers are these
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
'email' => [ // Add this configuration for email verification
'driver' => 'session',
'provider' => 'users',
],
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'mongodb' => [
'driver' => 'session',
'provider' => 'users',
],
// for API
'api' => [
'driver' => 'sanctum',
'provider' => 'api_users', // Use the 'api_users' provider for API authentication
],
'api_users' => [
'driver' => 'sanctum',
'provider' => 'api_users',
],
],
'verification' => [
'enabled' => false,
'expire' => 60,
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'api_users' => [
'driver' => 'eloquent',
'model' => App\Models\ApiUser::class, // Use the ApiUser model for API authentication
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
'password_timeout' => 10800,
];
i have tried going through many online resources including Laravel official documentation and still cannot find a solution. i have also tried deleting and recreating the model and controller but i arrive to the same error when it comes to token generation, other endpoints if work fine so far even creation of new records in database.
how can i resolve this?
I managed to find the solution to this and it was by changing vendor file located at
vendor/laravel/sanctum/src/PersonalAccessToken.phpI change the statementuse Illuminate\Database\Eloquent\Model;touse MongoDB\Laravel\Eloquent\Model;@sahandi81 here