如何通过Sanctum API登录后保护Laravel客户端应用路由
实现客户端应用路由保护的方案
由于客户端应用没有数据库,无法直接使用Laravel默认的auth中间件,我们需要通过验证本地存储的Sanctum令牌有效性 + 自定义中间件来实现路由保护,具体操作步骤如下:
1. 创建自定义认证中间件
在客户端应用中生成一个专属的认证中间件,比如CheckSanctumAuthenticated:
php artisan make:middleware CheckSanctumAuthenticated
2. 编写中间件验证逻辑
打开生成的app/Http/Middleware/CheckSanctumAuthenticated.php,替换handle方法的内容:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Http; use Symfony\Component\HttpFoundation\Response; class CheckSanctumAuthenticated { public function handle(Request $request, Closure $next): Response { // 从session中获取存储的Sanctum令牌(如果是SPA可改用localStorage,需对应调整) $token = $request->session()->get('sanctum_token'); if (!$token) { // 无令牌时直接跳转登录页 return redirect()->route('login'); } // 调用后端API的用户验证接口,确认令牌有效性 $response = Http::withToken($token)->get(config('app.api_url').'/api/user'); if ($response->failed()) { // 令牌无效,清除本地存储并跳转登录 $request->session()->forget('sanctum_token'); return redirect()->route('login')->with('error', '登录已过期,请重新登录'); } // 将后端返回的用户信息存入请求,方便后续业务使用 $request->merge(['user' => $response->json()]); return $next($request); } }
3. 注册自定义中间件
打开app/Http/Kernel.php,在routeMiddleware数组中添加中间件别名:
protected $routeMiddleware = [ // ... 保留原有其他中间件 'sanctum.auth' => \App\Http\Middleware\CheckSanctumAuthenticated::class, ];
4. 替换路由中的中间件
把原来路由组里的auth中间件换成自定义的sanctum.auth:
Route::middleware(['sanctum.auth'])->group(function () { Route::get('/customers', [CustomerController::class, 'index'])->name('customer.index'); });
5. 确保后端提供验证接口
后端API应用需要有一个验证用户身份的接口,Laravel Sanctum默认已经提供/api/user路由,只需确保它处于auth:sanctum中间件保护下:
// 后端API的routes/api.php Route::middleware('auth:sanctum')->get('/user', function (Request $request) { return $request->user(); });
关于权限验证(原can:view customers逻辑)
因为客户端没有权限系统,权限判断需要调用后端API完成,有两种实现方式:
- 在自定义中间件中增加权限验证逻辑,调用后端的权限检查接口
- 在控制器方法内先验证权限,再执行业务逻辑
控制器内权限验证示例
public function index(Request $request) { $token = $request->session()->get('sanctum_token'); // 调用后端权限检查接口 $permissionResponse = Http::withToken($token)->get(config('app.api_url').'/api/check-permission/view-customers'); if ($permissionResponse->failed()) { abort(403, '无访问权限'); } // 调用后端API获取客户列表 $customers = Http::withToken($token)->get(config('app.api_url').'/api/customers')->json(); return view('customers.index', compact('customers')); }
后端权限检查接口示例
// 后端API的routes/api.php Route::middleware('auth:sanctum')->get('/check-permission/{permission}', function (Request $request, $permission) { $permissionName = str_replace('-', ' ', $permission); if ($request->user()->can($permissionName)) { return response()->json(['allowed' => true]); } return response()->json(['allowed' => false], 403); });
内容的提问来源于stack exchange,提问作者steve code
相关产品推荐
相关产品推荐

