Laravel 11 RESTful API配置:实现异常与认证JSON响应
解决Laravel API返回JSON而非视图/重定向的问题
问题场景
开发RESTful API时,遇到两种不符合预期的情况:
- 触发404异常时返回HTML视图
- 使用Sanctum登出或未认证访问时,被重定向到登录页面而非返回JSON响应
当前config/auth.php配置如下:
/* |-------------------------------------------------------------------------- | Authentication Defaults |-------------------------------------------------------------------------- | | This option defines the default authentication "guard" and password | reset "broker" for your application. You may change these values | as required, but they're a perfect start for most applications. | */ 'defaults' => [ 'guard' => env('AUTH_GUARD', 'web'), 'passwords' => env('AUTH_PASSWORD_BROKER', 'users'), ], /* |-------------------------------------------------------------------------- | Authentication Guards |-------------------------------------------------------------------------- | | Next, you may define every authentication guard for your application. | Of course, a great default configuration has been defined for you | which utilizes session storage plus the Eloquent user provider. | | All authentication guards have a user provider, which defines how the | users are actually retrieved out of your database or other storage | system used by the application. Typically, Eloquent is utilized. | | Supported: "session" | */ 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], ], /* |-------------------------------------------------------------------------- | User Providers |-------------------------------------------------------------------------- | | All authentication guards have a user provider, which defines how the | users are actually retrieved out of your database or other storage | system used by the application. Typically, Eloquent is utilized. | | If you have multiple user tables or models you may configure multiple | providers to represent the model / table. These providers may then | be assigned to any extra authentication guards you have defined. | | Supported: "database", "eloquent" | */ 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => env('AUTH_MODEL', App\Models\User::class), ], // 'users' => [ // 'driver' => 'database', // 'table' => 'users', // ], ], /* |-------------------------------------------------------------------------- | Resetting Passwords |-------------------------------------------------------------------------- | | These configuration options specify the behavior of Laravel's password | reset functionality, including the table utilized for token storage | and the user provider that is invoked to actually retrieve users. | | The expiry time is the number of minutes that each reset token will be | considered valid. This security feature keeps tokens short-lived so | they have less time to be guessed. You may change this as needed. | | The throttle setting is the number of seconds a user must wait before | generating more password reset tokens. This prevents the user from | quickly generating a very large amount of password reset tokens. | */ 'passwords' => [ 'users' => [ 'provider' => 'users', 'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'), 'expire' => 60, 'throttle' => 60, ], ], /* |-------------------------------------------------------------------------- | Password Confirmation Timeout |-------------------------------------------------------------------------- | | Here you may define the amount of seconds before a password confirmation | window expires and users are asked to re-enter their password via the | confirmation screen. By default, the timeout lasts for three hours. | */ 'password_timeout' => env('AUTH_PASSWORD_TIMEOUT', 10800),
注:路由定义在api.php中
解决方案
1. 配置API专属认证守卫
Laravel默认使用web守卫(基于Session),API需要切换为sanctum守卫(基于令牌)。修改config/auth.php:
- 在
guards数组中添加api守卫 - 将默认守卫切换为
api(或在路由中明确指定auth:sanctum)
修改后的defaults和guards部分:
'defaults' => [ 'guard' => env('AUTH_GUARD', 'api'), // 切换默认守卫为api 'passwords' => env('AUTH_PASSWORD_BROKER', 'users'), ], 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'sanctum', 'provider' => 'users', 'hash' => false, ], ],
2. 强制API请求返回JSON响应
修改异常处理器,让API路由下的404、认证异常直接返回JSON格式响应:
打开app/Exceptions/Handler.php,在register方法中添加以下逻辑:
use Illuminate\Auth\AuthenticationException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; $this->renderable(function (NotFoundHttpException $e, $request) { if ($request->is('api/*')) { return response()->json([ 'message' => '资源未找到' ], 404); } }); $this->renderable(function (AuthenticationException $e, $request) { if ($request->is('api/*')) { return response()->json([ 'message' => '未授权访问' ], 401); } });
这段代码会检测请求是否来自API路由,若是则返回JSON错误,而非视图或重定向。
3. 确保API路由使用正确中间件
api.php中的路由默认已包含api中间件组,但需要认证的路由必须使用auth:sanctum中间件,而非web端的auth中间件:
// 示例:需要认证的API路由组 Route::middleware('auth:sanctum')->group(function () { Route::post('/logout', [AuthController::class, 'logout']); // 其他需要认证的API路由... });
内容的提问来源于stack exchange,提问作者Luis Garcia
相关产品推荐
相关产品推荐

