如何强制 Laravel API 始终返回 JSON,不重定向

Posted

技术标签:

【中文标题】如何强制 Laravel API 始终返回 JSON,不重定向【英文标题】:How to force Laravel API to always return JSON, no redirects 【发布时间】:2021-06-01 13:54:50 【问题描述】:

我有一个 Laravel 应用程序,我构建它只用作 JSON API。它没有任何意见,仅支持我们的第一方 SPA。它使用 Laravel 8、Fortify 和 Sanctum。我的 SPA 位于 my-app.test,api 位于 api.my-app.test。 SPA 按预期工作。但是,如果我在浏览器中访问我经过身份验证的 API 路由之一,例如api.my-app.test/someResource,我收到一个错误页面,告诉我“Route [login] not defined.”,堆栈跟踪显示此代码:

vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php:393

protected function unauthenticated($request, AuthenticationException $exception)

  return $request->expectsJson()
    ? response()->json(['message' => $exception->getMessage()], 401)
    : redirect()->guest($exception->redirectTo() ?? route('login'));

我有以下文件,我尝试覆盖 redirectTounauthenticated 方法,但它不起作用: app/Http/Middleware/Authenticate.php

protected function unauthenticated($request, array $guards): JsonResponse

  return response()->json(['message' => 'Unauthenticated.'], Response::HTTP_UNAUTHORIZED);


protected function redirectTo($request)

  return response()->json(['message' => 'Unauthenticated.'], Response::HTTP_UNAUTHORIZED);

当我在上面实现unauthenticated 时,它似乎不再对我的任何路由进行身份验证,命中任何 API 端点都会返回应该受到保护的结果。当我在上面实现redirectTo 时,我收到另一个错误消息“标题可能不包含多个标题,检测到新行”,我不确定从那里去哪里。

全局禁用所有视图和重定向并强制 Laravel 始终返回 JSON 的正确方法是什么?有没有办法覆盖expectsJson

【问题讨论】:

【参考方案1】:

你也可以覆盖app/Exceptions/Handler.php中的unauthenticated函数:

protected function unauthenticated($request, AuthenticationException $exception)

    return response()->json(['message' => $exception->getMessage()], 401);

【讨论】:

【参考方案2】:

只需处理App\Exceptions\Handler 中的AuthenticationException,如下所示:

public function render($request, Throwable $exception)

    if ($exception instanceof AuthenticationException) 
        return response()->json(["error"=>30001, "message"=>"authenticate failed"]);
    
    return parent::render($request, $exception);

【讨论】:

如果您使用像 Postman 这样的 REST 客户端进行测试,请确保将 AcceptContent-Type 标头设置为 application/json

以上是关于如何强制 Laravel API 始终返回 JSON,不重定向的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 强制 json 响应 api

如何在 Laravel 中接收单引号 JSON

Laravel 8 API 调用未正确返回验证错误

如何强制实体框架始终从数据库中获取更新数据?

如何使用 Laravel API 身份验证返回未授权

Api 调用 Laravel 8 后如何从控制器返回视图?