Laravel文件下载接口报500错误:Route [login]未定义
Laravel文件下载500错误排查与解决
问题场景
使用Laravel开发时,从storage获取文件下载链接触发500错误,请求携带的token验证正常。FilesController的store方法可正常完成文件上传,但show方法无法工作,AuthController所有功能正常。
错误日志
Symfony\Component\Routing\Exception\RouteNotFoundException: Route [login] not defined。
相关代码文件
api.php
<?php use App\Http\Controllers\AuthController; use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; use App\Http\Controllers\FilesController; Route::fallback(function () { return abort(404); // return view('errors.404'); // incase you want to return view }); Route::middleware(['auth:sanctum', 'ability:admin'])->get('/user', function (Request $request) { if($request->user()->role == "user") return abort(403); return response($request->user(), 200); }); Route::get('/auth/test', [AuthController::class, 'test'])->middleware(['auth:sanctum', 'ability:admin']); Route::post('/auth/register', [AuthController::class, 'register']); Route::post('/auth/login', [AuthController::class, 'login']); Route::post('/auth/logout', [AuthController::class, 'logout'])->middleware('auth:sanctum'); Route::group(['middleware' => ['auth:sanctum','ability:admin']], function() { Route::resource('files', FilesController::class); });
AuthController.php
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\User; use Illuminate\Http\Response; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Auth; class AuthController extends Controller { public function register(Request $request) { $data = $request->validate([ 'name' => 'required|string', 'email' => 'required|string|unique:users,email', 'password' => 'required|string|' ]); $user = User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => bcrypt($data['password']), 'role' => 'admin' ]); $token = $user->createToken('token', [$user->role])->plainTextToken; $res = [ 'user' => $user, 'token' => $token ]; return response($res, 201); } public function login(Request $request) { $data = $request->validate([ 'email' => 'required|string', 'password' => 'required|string' ]); $user = User::where('email', $data['email'])->first(); if (!$user || !Hash::check($data['password'], $user->password)) { return response([ 'message' => 'incorrect username or password' ], 401); } $token = $user->createToken('token', [$user->role])->plainTextToken; $res = [ 'user' => $user, 'token' => $token ]; return response($res, 201); } public function logout(Request $request) { $request->user()->tokens()->delete(); $response = ['message' => 'You have been successfully logged out!']; return response($response, 200); } public function test(Request $request) { if($request->user()->role == "user") return response(['message' => 'user'], 200); if($request->user()->role == "admin") return response(['message' => 'admin'], 200); }}
FilesController.php
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; use Symfony\Component\HttpFoundation\File\File; class FilesController extends Controller { public function index() { // } /** * Show the form for creating a new resource. */ public function create() { // } /** * Store a newly created resource in storage. */ public function store(Request $request) { $data = $request->validate([ 'file' => 'required|mimes:pdf|max:2048' ]); if ($file = $request->file('file')) { $path = $file->store('public/files'); $name = $file->getClientOriginalName(); $name2 = $file->hashName(); // //store your file into directory and db // $save = new File(); // $save->name = $file; // $save->store_path = $path; // $save->save(); return response()->json([ "success" => true, "message" => "File successfully uploaded", "file" => $file, "name" => $name, //oryginalna nazwa pliku "path" => $path, // path do pliku np. "public/files/wy8NNSV9uAvL0NPYydw5iaZDkz5XQYeFo2A7VZo0.pdf" "name2" => $name2 // sama nazwa pliku np. "wy8NNSV9uAvL0NPYydw5iaZDkz5XQYeFo2A7VZo0.pdf" ]); } } /** * Display the specified resource. */ public function show(string $filename) { // tutaj powinno być id pliku i z bazy nazwa ale jako id tutaj przekazana jest nazwa pliku z storage $file = new File(Storage::disk('public_files')->get($filename)); return response()->download($file->getRealPath(), $filename); } /** * Show the form for editing the specified resource. */ public function edit(string $id) { // } /** * Update the specified resource in storage. */ public function update(Request $request, string $id) { // } /** * Remove the specified resource from storage. */ public function destroy(string $id) { // }}
config/filesystems.php
'public_files' => [ 'driver' => 'local', 'root' => storage_path('app/public/files'), 'url' => env('APP_URL').'/storage/files', 'visibility' => 'public', ],
文件结构

问题分析与解决方案
核心原因
- 错误提示
Route [login] not defined,是因为response()->download()触发了Laravel的ShareErrorsFromSession中间件,该中间件默认尝试跳转至web端的login命名路由,但API路由中未定义此路由。 - FilesController的show方法存在文件操作错误:
Storage::disk('public_files')->get($filename)返回的是文件内容而非路径,直接传入File类构造器会导致实例化失败。
修复步骤
修正FilesController的show方法:
替换原show方法代码,使用正确的文件路径获取方式,同时避免触发web认证跳转逻辑:public function show(string $filename) { $disk = Storage::disk('public_files'); if (!$disk->exists($filename)) { return response()->json(['message' => '文件不存在'], 404); } $filePath = $disk->path($filename); return response()->download($filePath, $filename)->withHeaders([ 'Cache-Control' => 'no-cache, no-store, must-revalidate', 'Pragma' => 'no-cache', 'Expires' => '0', ]); }验证API路由匹配:
确认files资源路由的show方法对应URL为/api/files/{file},请求时需传入上传接口返回的name2字段值作为文件名参数。确认API中间件配置:
确保routes/api.php未加载web端的会话、认证中间件(Laravel默认已通过RouteServiceProvider排除,若有自定义配置需检查)。
内容的提问来源于stack exchange,提问作者MISIU
相关产品推荐
相关产品推荐

