未找到带有api 401错误的Laravel 8路由登录



Am使用laravel 8,并在我的api路由中使用auth:api中间件。在我的请求url中,我使用passport生成的令牌Bearer token设置了正确的承载令牌。这工作得很好,但每当请求有一个过期的令牌时,它就会抛出一个未定义的路由[登录]错误

我在我的api路由中有以下内容

Route::middleware("auth:api")->group(function (){
Route::resource("users",UserController::class);
});

我还在我的appExceptionsHandler.php中添加了以下内容

class Handler extends ExceptionHandler
{
public function report(Throwable $exception)
{
if ($exception instanceof LeagueOAuth2ServerExceptionOAuthServerException && $exception->getCode() == 9) {
return response('unauthorized', 401);
}
parent::report($exception);
}
}

但是以上这些仍然不起作用。我需要添加什么才能使其工作。

这是因为Laravel可能正在抛出AuthenticationException异常。该逻辑在方法unauthenticated():中的默认Illuminate/Foundation/Exceptions/Handler.php中定义
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
return redirect()->guest(route('login'));
}

正如您所看到的,在这个默认示例中,如果您的API超出JSON响应,那么您将使用401 HTTP代码获得JSON响应。如果不是这样,您将被重定向到登录(因此出现错误,因为您没有定义登录路由(

所以,为了解决这个问题,你可以做两件事。

第一个是重写这个方法,并实际编写自己的条件和响应。您可以通过在自定义Handler.php中定义unauthenticated()方法来实现这一点。你可以这样做:

protected function unauthenticated($request, AuthenticationException $exception)
{
//This will return just a plain 401 page
return response('Unauthenticated.', 401);
}

但是,由于这可能是一个API,因此最好使用第二种解决方案,即只在请求头中包含Accept: application/json。这个消息会告诉你的API你正在发送一个JSON请求。在这种情况下,您不需要重写unauthenticated(),因为此异常将在以下条件下从默认的Laravel处理程序捕获:

if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}

当这个代码块被触发时,您将得到一个JSON响应,其中包含401个HTTP代码,这是API的预期代码。如果你需要更多的帮助,请告诉我。

最新更新