基于角色的Laravel Sanctum SPA认证实现问题(独立管理员表)
Hey there! I’ve worked through this exact setup before, so let’s break down how to get your separate admin table integrated with Sanctum properly. Here’s the step-by-step implementation:
1. Create Admin Model & Migration
First, generate your Admin model and migration file. Don’t forget the HasApiTokens trait—it’s required for Sanctum to generate tokens:
// app/Models/Admin.php namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Laravel\Sanctum\HasApiTokens; class Admin extends Authenticatable { use HasApiTokens; protected $fillable = [ 'name', 'email', 'password', ]; protected $hidden = [ 'password', 'remember_token', ]; protected $casts = [ 'email_verified_at' => 'datetime', ]; }
For the migration, create a admins table with all necessary fields:
// database/migrations/xxxx_xx_xx_xxxxxx_create_admins_table.php public function up() { Schema::create('admins', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); }
Run the migration with php artisan migrate.
2. Configure config/auth.php
Update your auth config to add a custom guard and provider for admins—this is where most people get stuck, so let’s be precise:
// config/auth.php 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], // Add this admin guard (uses Sanctum driver) 'admin' => [ 'driver' => 'sanctum', 'provider' => 'admins', ], ], 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\Models\User::class, ], // Add this admin provider pointing to your Admin model 'admins' => [ 'driver' => 'eloquent', 'model' => App\Models\Admin::class, ], ], // Optional: Add password reset config if you need admin password resets 'passwords' => [ 'users' => [ 'provider' => 'users', 'table' => 'password_resets', 'expire' => 60, 'throttle' => 60, ], 'admins' => [ 'provider' => 'admins', 'table' => 'admin_password_resets', 'expire' => 60, 'throttle' => 60, ], ],
3. Update Sanctum Configuration
Make sure your SPA’s domain is listed in Sanctum’s stateful domains so it can handle session-based auth for your frontend:
// config/sanctum.php 'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( '%s%s', 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : '' ))),
Add your frontend domain here (e.g., localhost:5173 for Vue/React projects).
4. Build Admin Authentication Controller
Create a controller to handle admin login, token generation, and logout:
// app/Http/Controllers/AdminAuthController.php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class AdminAuthController extends Controller { public function login(Request $request) { $request->validate([ 'email' => 'required|email', 'password' => 'required', ]); // Use the admin guard to authenticate credentials if (!Auth::guard('admin')->attempt($request->only('email', 'password'))) { return response()->json([ 'message' => 'Invalid credentials' ], 401); } // Generate a Sanctum token for the authenticated admin $admin = Auth::guard('admin')->user(); $token = $admin->createToken('admin-access-token')->plainTextToken; return response()->json([ 'admin' => $admin, 'token' => $token, ]); } public function logout(Request $request) { // Revoke the current admin's token $request->user()->currentAccessToken()->delete(); return response()->json([ 'message' => 'Logged out successfully' ]); } }
5. Define Protected Admin Routes
Add routes for admin auth and protected endpoints, specifying the admin guard in the middleware to enforce admin-only access:
// routes/api.php use App\Http\Controllers\AdminAuthController; // Public admin login route Route::post('/admin/login', [AdminAuthController::class, 'login']); // Protected admin routes (requires valid admin Sanctum token) Route::middleware(['auth:sanctum', 'auth:admin'])->group(function () { Route::post('/admin/logout', [AdminAuthController::class, 'logout']); Route::get('/admin/dashboard', function () { return response()->json([ 'message' => 'Welcome to the admin dashboard', 'admin' => auth()->user() ]); }); });
Key Troubleshooting Tips
- CORS Setup: Ensure
config/cors.phphassupports_credentialsset totrueand your frontend domain is inallowed_origins. - Frontend Requests: For authenticated calls, include the
Authorization: Bearer {token}header. For SPAs, you’ll also need to handle the XSRF token (Sanctum sets this automatically via a cookie). - Token Scopes: If you need granular permissions, add scopes when creating tokens (e.g.,
$admin->createToken('admin-token', ['manage-users'])->plainTextToken) and validate them with theabilitymiddleware.
内容的提问来源于stack exchange,提问作者teranshil

