I am having some problems getting Laravel Sanctum authorising two tables in two separate databases.
I am using Laravel Sanctum tokens for authorisation. I have two tables to authorise users (users & contacts) I have setup two separate guards and can get everything to work on a single database with one token table.
However I want to have the contacts table in a separate database. Doing so creates two personal_access_tokens tables, one in the Users database and the other in the Contacts database, which I don't mind. I can create the tokens just fine, however when I try to authorise contacts using a token, Sanctum is trying to look in the Users personal_access_tokens table, not the Contacts personal_access_tokens table. So essentially it's just looking at the wrong database for the personal_access_tokens table and I don't know how to change that.
My setup is as follows:
Guards:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
/*'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],*/
'users' => [
'driver' => 'sanctum',
'provider' => 'users',
'hash' => false,
],
'contacts' => [
'driver' => 'sanctum',
'provider' => 'contacts',
'hash' => false,
],
],
Providers
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'contacts' => [
'driver' => 'eloquent',
'model' => App\Models\Contact::class,
],
],
User Model
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
Contact Model
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class Contact extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The connection name for the model.
*
* @var string
*/
protected $connection = 'puranet_crm';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'first_name',
'last_name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
My two api routes for autorisation are:
Route::group(['middleware' => 'auth:sanctum'], function() {
//All secure URL's
Route::get('test',[UserController::class, 'test']);
});
Route::group(['middleware' => 'auth:contacts'], function() {
Route::get('test-contacts',[ContactController::class, 'test']);
});
Contact Controller (this is identical to the UserController with exception to the Model it is referencing)
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Contact;
use Illuminate\Support\Facades\Hash;
class ContactController extends Controller
{
/**
* @param Request $request
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function login(Request $request)
{
$user = Contact::where('email', $request->email)->first();
if (!$user || !Hash::check($request->password, $user->password)) {
return response([
'message' => ['These credentials do not match our records.']
], 404);
}
$token = $user->createToken('contacts-app-token')->plainTextToken;
$response = [
'user' => $user,
'token' => $token
];
return response($response, 201);
}
/**
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function test()
{
return response(["response" => "Test Contacts"], 201);
}
}