Laravel 8 API 中出现 "route not defined" 错误的原因是什么?

What causes the "route not defined" error in this Laravel 8 API?

我正在使用 Laravel 8 和 Angular 13 编写注册表。后端是 API (link 到 Github 回购)。在 UserController 中,我有一个 signin() 和一个 signout() 方法

用户控制器

public function signin(Request $request)
{
    $fields = $request->validate([
        'email' => 'required|string',
        'password' => 'required|string'
    ]);

    // Check email
    $user = User::where('email', $fields['email'])->first();

    // Check password
    if (!$user || !Hash::check($fields['password'], $user->password)) {
        return response(['message' => 'Incorrect email and/or password'], 401);
    }

    $token = $user->createToken('secret-token')->plainTextToken;

    $response = [
        'user' => $user,
        'token' => $token
    ];

    return response($response, 201);
}

public function signout(Request $request)
{
    auth()->user()->tokens->each(function ($token) {
        $token->delete();
    });

    return [
        'message' => 'You have been signed out.'
    ];
}

routes\api.php

Route::post('/signup', [UserController::class, 'signup']);
Route::post('/signin', [UserController::class, 'signin']);

Route::group(['middleware' => ['auth:sanctum']], function () {
    Route::post('/signout', [UserController::class, 'signout']);
});

问题

我在 Postman 中访问 https://mysite.test/api/signout 时出现错误。

Route [login] not defined.

我的错误在哪里?

它命中身份验证中间件,默认情况下它会将您重定向到路由 ('login')。这是因为当您删除令牌时,用户无法通过 auth:sanctum 进行访问,因此它将未经身份验证的用户重定向到不存在的登录路由。只需将 Middleware/Authenticate 中的重定向更改为 signin/signout 路由。

将控制器中的 singout() 更改为此

Auth::guard($this->guard())->logout();

Request::session()->invalidate();

Request::session()->regenerateToken();

这将在不点击身份验证中间件的情况下注销用户,它将 return 204 或无内容的 json 响应。注意:只需更改您的 set guard 而不是 $this->guard() 我建议在您的 UserController 中添加一个私有函数,这样您每次都可以获得正确的 guard,看起来像这样

if(isset($this->guard) && $this->guard) {
    return $this->guard;
}

return config('auth.defaults.guard');

在 headers(postman) 中,添加以下键值

接受:application/json

在你的App\Http\Kernel.php

替换

    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
...

    protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
...

但仅此一项并不能解决问题。

在你的App\Exceptions\Handler.php

将此方法添加到 class

    protected function unauthenticated($request, \Illuminate\Auth\AuthenticationException $exception)
    {
        return response()->json(['message' => $exception->getMessage()], 401);
    }

原因是 Laravel 在处理 AuthenticationException.

时如何检测请求 shouldReturnJson

您表明您希望通过发送
得到json回复 Accept: application/json(不是Accept */*)请求header.

这是您的场景:

您的 signout 路由在 auth 中间件后面。 您被检测为访客(可能您没有正确发送身份验证 header?)并且您不想要 json 响应(丢失的 json 接受 header ).此时 Laravel 通过 default 将您重定向到 login

in laravel 8 修改路由文件(或配置文件)后必须使用 php artisan optimize 命令