Laravel Sanctum认证后JSON文件仍可未授权访问的问题
问题分析与解决办法
你当前的路由配置完全无效:路由定义不能嵌套在另一个路由的闭包里,而且直接指向外部JSON文件URL的写法,根本起不到认证保护作用——客户端直接访问那个JSON链接就绕开了Laravel的认证流程。
正确处理方式
方案一:将JSON文件移到Laravel项目内(推荐)
把JSON文件放到Laravel私有目录下,通过API路由控制访问:
- 在项目中新建目录
storage/app/json_files,将所有JSON文件移入该目录(此目录默认外部无法直接访问)。 - 修改
routes/api.php,添加受Sanctum保护的路由:
// 所有需要认证的JSON访问路由都放在这个组里 Route::middleware('auth:sanctum')->group(function () { // 单个文件路由 Route::get('/lecons/lecon1', function () { $filePath = storage_path('app/json_files/lecon1.json'); if (!file_exists($filePath)) { return response()->json(['message' => '文件不存在'], 404); } return response()->file($filePath); }); // 动态匹配多个文件的简化写法 Route::get('/lecons/{filename}', function ($filename) { $filePath = storage_path("app/json_files/{$filename}.json"); if (!file_exists($filePath)) { return response()->json(['message' => '文件不存在'], 404); } return response()->file($filePath); }); }); // 保留原有注册、登录路由 Route::post('api/inscription', [AuthController::class, 'InscrisUtilisateur']); Route::post('api/connexion', [AuthController::class, 'connexion']);
之后客户端必须先登录获取Sanctum令牌,再请求 /api/lecons/lecon1 这类接口才能拿到JSON内容,直接访问原外部URL会失效。
方案二:代理外部服务器的JSON文件(仅限无法迁移文件时使用)
如果JSON必须留在外部服务器,通过Laravel做身份验证后的代理转发:
Route::middleware('auth:sanctum')->group(function () { Route::get('/lecons/lecon1', function () { // 使用Laravel Http客户端请求外部文件 $response = Http::get('https://jsonfile.ubix-group.com/lecons/lecon1.json'); if ($response->failed()) { return response()->json(['message' => '获取文件失败'], $response->status()); } return response($response->body(), $response->status())->header('Content-Type', 'application/json'); }); });
注意:必须给外部服务器配置IP白名单,只允许你的Laravel服务器访问,否则他人仍可直接访问外部JSON链接。
内容的提问来源于stack exchange,提问作者Nathalie taffot
相关产品推荐
相关产品推荐

