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
命令
我正在使用 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
命令