一般而言,我們都會希望控管使用者在系統內的權限,而 Laravel 提供了非常便利的工具,無論是預設或是客製驗證流程都很方便。
目前專案透過 SSO(如 Keycloak)登入後會取得一組 JWT Token。
Laravel 認證流程改為使用 自訂的 guard 和 user provider 來支援這種驗證邏輯。
config/auth.php 設定:
'guards' => [
    'api' => [
        'driver' => 'sso',       // 自訂 guard
        'provider' => 'custom',  // 對應的 user provider
    ],
],
'providers' => [
    'custom' => [
        'driver' => 'custom',    // 自訂 user provider
    ],
],
app/Auth/CustomApiProvider.php
namespace App\Auth;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Auth\GenericUser;
class CustomApiProvider implements UserProvider
{
    public function retrieveByCredentials(array $credentials)
    {
        // 模擬從 JWT token 解析出 user info
        $user = [
            'id' => 1,
            'employeeNo' => 'A001',
            'name' => 'Harry',
            'jobName' => 'Engineer',
            'access' => 'admin',
        ];
        return $this->getGenericUser($user);
    }
    public function getGenericUser(array $user)
    {
        return new GenericUser($user);
    }
    // 其他方法為了相容性可簡單實作或留空
    public function retrieveById($identifier) {}
    public function retrieveByToken($identifier, $token) {}
    public function updateRememberToken(Authenticatable $user, $token) {}
    public function validateCredentials(Authenticatable $user, array $credentials) {
        return true;
    }
}
app/Providers/AppServiceProvider.php
use App\Auth\CustomApiProvider;
use Illuminate\Support\Facades\Auth;
use Illuminate\Contracts\Foundation\Application;
public function boot(): void
{
    Auth::provider('custom', function (Application $app, array $config) {
        return new CustomApiProvider();
    });
}
php artisan make:middleware RoleCheck
app/Http/Middleware/RoleCheck.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class RoleCheck
{
    public function handle(Request $request, Closure $next): Response
    {
        $user = Auth::user();
        // 這裡以 admin 為例,視情況修改權限邏輯
        if (!$user || $user->access !== 'admin') {
            return response()->json(['message' => 'Forbidden'], 403);
        }
        return $next($request);
    }
}
app/Http/Kernel.php
protected $routeMiddleware = [
    // ...
    'role.check' => \App\Http\Middleware\RoleCheck::class,
];
routes/api.php
use Illuminate\Support\Facades\Route;
Route::middleware(['auth:api', 'role.check'])->group(function () {
    Route::get('/', function () {
        return response()->json([
            'status' => 'success',
            'user' => Auth::user(),
        ]);
    });
});
如此一來就可以透過客製的驗證方式來驗證使用者權限!