Laravel Fortify 不响应 HTTP 代码,而是响应实际路由,即使我将注册请求作为 XHR 请求发送也是如此

Laravel Fortify doesn't respond with HTTP code but with actual routes, even if I send the registration request as an XHR one

上下文

使用 Postman,为了在数据库中注册用户,我将以下字段发送到 URL http://mywebsite/register:

根据文档 https://laravel.com/docs/8.x/fortify#registration(我从中找到了上述字段),Fortify 已经定义了路由 register,所以我不需要自己定义它。

根据文档和我的需要,我不需要创建注册表单:我直接使用 Postman 将这些注册数据发送到 Laravel Fortify 的路由 /register 作为 XHR POST 请求数据。此外,我不需要 Fortify 到 return 的视图,所以我禁用了它们 (https://laravel.com/docs/8.x/fortify#disabling-views)。事实上,我只是等待我将在 Postman 的 return 数据中看到的 HTTP 代码响应(见下文)。

Fortify 应该 return

因为我已经禁用了视图并且因为我发送了一个 XHR POST 请求(在 Postman 中我发送了这个 HTTP header 以及注册请求:X-Requested-With = XMLHttpRequest) :

If the registration attempt is successful, Fortify will redirect the user to the URI configured via the home configuration option within your application's fortify configuration file. If the login request was an XHR request, a 200 HTTP response will be returned.

If the request was not successful, the user will be redirected back to the registration screen and the validation errors will be available to you via the shared $errors Blade template variable. Or, in the case of an XHR request, the validation errors will be returned with a 422 HTTP response.

(https://laravel.com/docs/8.x/fortify#registration)

实际上Fortify是什么return

它正确地注册了用户。但是我在 Postman 中看到的结果是 Symfony\Component\HttpKernel\Exception\NotFoundHttpException。确实,Fortify 正在尝试到达主视图。

问题

为什么 Fortify 似乎仍然试图到达 returned 视图路由(未定义,因为我不需要它们),因为我的请求正确地是一个 XHR POST一是因为我在 Fortify 配置文件中禁用了视图?

将配置变量 views 设置为 false 将不起作用,因为它只会禁用呈现 fortify 的视图文件,如登录页面、注册页面、重置密码页面等。

Fortify 路由默认使用中间件 [web] 您需要在将视图设置为 false 的同一配置文件中将此中间件值设置为 [api]。

我想我在 Fortify 文档 (https://laravel.com/docs/8.x/fortify#registration) 中发现了一些“有趣”的东西。那里有些东西不完整。我想我已经找到了文档中缺少的内容!

我解释一下。

在我的例子中,phone 应用程序显示注册表单。它将 Fortify 的注册必填字段(如 email, password, confirmation_password, ...)发送到由 Fortify 定义的 URL <LaravelSite>/register。 Fortify 成功注册用户并将其重定向到主路由。 但是,我没有定义任何归途路线,因为如您所知,这个 Laravel 站点是一个 API。 结果 => 我有这个错误:Symfony\Component\HttpKernel\Exception\NotFoundHttpException.

我遵循了文档:我已经禁用了视图(在 Fortify 配置文件中)。我已经正确指定 phone 应用程序(实际上是 Postman)发送的请求是一个 XHR 请求(事实上,我已经发送了 header X-Requested-With = XMLHttpRequest)。 所以 Fortify 应该 return 我一个 HTTP 代码(200 这里)而不是试图 return 我回家 URL.

文档中缺少什么? =====>>>> 中间件 RedirectIfAuthenticated 被执行。在它的句柄方法中有一个重定向:return redirect(RouteServiceProvider::HOME);。为了使 Fortify 正常工作,必须通过注释禁用此行。

Fortify 文档应该包含类似上述句子的内容。

应该在他们的 Github 存储库上创建 PR 或问题。

编辑: 我们还必须发送这个 HTTP header:Accept: application/json(否则如果注册成功,它仍然会显示 404)

顺便说一句,我遇到了完全相同的问题。经过 30 分钟的在线搜索,我最终检查了我信任的 Laracast 数据库,并且确定我找到了一个 5 分钟的视频,告诉我如何(以某种方式)解决这个问题。

https://laracasts.com/series/laravel-authentication-options/episodes/15

简而言之,您需要做的就是将 register 路由添加到您的 routes/api.php 文件。路由的代码可以从 Fortify 供应商目录中复制: vendor/laravel/fortify/routes/routes.php。复制第 72/73 行的注册路由。将其粘贴到 api.php。 POST 现在将您的请求发送至 api/register,它将像在视频中一样工作。

希望对您有所帮助

如@JarsOfJam-Scheduler 所述,问题出在 RedirectIfAuthenticated 中间件上。您可以通过添加检查在 RedirectIfAuthenticated 中间件中禁用 xhr 请求的重定向。

if(!$request->wantsJson()){
    return redirect(RouteServiceProvider::HOME);
}

并且不要忘记将 header 添加到 axios

'Accept': 'application/json',
'Content-Type': 'application/json'