Laravel作为REST API调用出现401 Unauthorized授权问题求助
问题描述
我用Angular开发前端应用,后端基于Laravel框架搭建REST API。已经创建了AuthController,登录后可以返回JWT令牌,Angular会把该令牌添加到请求头里,但调用UserController的getUsers等接口时返回401未授权错误,不确定是不是中间件使用错误或者遗漏了配置。相关代码如下:
AuthController代码
<?php namespace App\Http\Controllers; use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Validator; use Tymon\JWTAuth\Facades\JWTAuth; use Tymon\JWTAuth\Exceptions\JWTException; class AuthController extends Controller { public function __construct() { $this->middleware('auth:api', ['except' => ['login', 'register']]); $this->middleware('auth:jwt', ['except' => ['login', 'register']]); } public function register(Request $request) { $validator = Validator::make($request->all(), [ 'name' => 'required|string', 'email' => 'required|email|unique:users', 'password' => 'required|min:6', ]); if ($validator->fails()) { return response()->json(['error' => $validator->errors()], 400); } $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => bcrypt($request->password), ]); $token = JWTAuth::fromUser($user); return response()->json(['token' => $token], 201); } public function login(Request $request) { $credentials = $request->only('email', 'password'); try { if (!$token = JWTAuth::attempt($credentials)) { return response()->json(['error' => 'Invalid credentials'], 401); } } catch (JWTException $e) { return response()->json(['error' => 'Could not create token'], 500); } return response()->json(['token' => $token]); } public function logout(Request $request) { try { JWTAuth::invalidate(JWTAuth::getToken()); } catch (JWTException $e) { return response()->json(['error' => 'Failed to logout'], 500); } return response()->json(['message' => 'Successfully logged out']); } }
UserController代码
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\User; use Tymon\JWTAuth\Exceptions\JWTException; use Tymon\JWTAuth\Facades\JWTAuth; class UserController extends Controller { public function __construct() { $this->middleware('auth:api'); $this->middleware('auth:jwt'); } public function getUsers() { try { JWTAuth::invalidate(JWTAuth::getToken()); } catch (JWTException $e) { return response()->json(['error' => 'Failed to getUsers()'], 500); } $users = User::all(); return response()->json($users); } public function deleteUser($id) { try { JWTAuth::invalidate(JWTAuth::getToken()); } catch (JWTException $e) { return response()->json(['error' => 'Failed to deleteUser()'], 500); } $user = User::findOrFail($id); $user->delete(); return response()->json(['message' => 'Użytkownik został usunięty']); } }
routes/api.php代码
Route::post('register', [AuthController::class, 'register']); Route::post('login', [AuthController::class, 'login']); Route::group(['middleware' => ['auth:api', 'auth:jwt']], function () { Route::post('logout', [AuthController::class, 'logout']); Route::get('users', [UserController::class, 'getUsers']); Route::delete('users/{id}', [UserController::class, 'deleteUser']); });
config/auth.php代码
'defaults' => [ 'guard' => 'api', 'passwords' => 'users', ], 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'jwt', 'provider' => 'users', ], 'jwt' => [ 'driver' => 'jwt', 'provider' => 'users', ], ],
问题分析与修复方案
1. 移除重复的Guard配置
你的config/auth.php中,api和jwt Guard均使用JWT驱动,功能完全重复,保留一个即可。建议删除冗余的jwt Guard:
'defaults' => [ 'guard' => 'api', 'passwords' => 'users', ], 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'jwt', 'provider' => 'users', ], ],
2. 删除重复的中间件验证
控制器和路由组中同时挂载了auth:api和auth:jwt中间件,双重验证会导致授权逻辑冲突,需统一保留auth:api:
- AuthController构造函数修改:
public function __construct() { $this->middleware('auth:api', ['except' => ['login', 'register']]); }
- UserController构造函数修改:
public function __construct() { $this->middleware('auth:api'); }
- routes/api.php修改:
Route::post('register', [AuthController::class, 'register']); Route::post('login', [AuthController::class, 'login']); Route::group(['middleware' => ['auth:api']], function () { Route::post('logout', [AuthController::class, 'logout']); Route::get('users', [UserController::class, 'getUsers']); Route::delete('users/{id}', [UserController::class, 'deleteUser']); });
3. 移除业务方法中的令牌失效代码
UserController的getUsers和deleteUser方法中错误调用了JWTAuth::invalidate,会导致每次请求后令牌直接失效,这是401错误的核心原因,需删除该逻辑:
- getUsers方法修改:
public function getUsers() { $users = User::all(); return response()->json($users); }
- deleteUser方法修改:
public function deleteUser($id) { $user = User::findOrFail($id); $user->delete(); return response()->json(['message' => '用户已删除']); }
4. 验证前端请求头格式
确保Angular前端将JWT令牌以Bearer {token}格式放入Authorization请求头:
// Angular请求示例 const headers = new HttpHeaders().set('Authorization', `Bearer ${token}`); this.http.get('/api/users', { headers }).subscribe(...);
5. 清理缓存
修改配置后执行以下命令清除Laravel缓存:
php artisan config:clear php artisan cache:clear
完成以上修改后重新测试接口,即可正常通过授权验证。
内容的提问来源于stack exchange,提问作者JanuszFrontEnd'u
相关产品推荐
相关产品推荐

