'What causes the "route not defined" error in this Laravel 8 API?
I am working on a registration form with Laravel 8 and Angular 13. The back-end is an API (link to Github repo). In the UserController I have a signin() and a signout() method
UserController
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']);
});
The problem
I get the error when I access https://mysite.test/api/signout in Postman.
Route [login] not defined.
Where is my mistake?
Solution 1:[1]
In your App\Http\Kernel.php
Replace
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
...
with
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
...
But that alone is not gonna cut it.
In your App\Exceptions\Handler.php
add this method to the class
protected function unauthenticated($request, \Illuminate\Auth\AuthenticationException $exception)
{
return response()->json(['message' => $exception->getMessage()], 401);
}
The reasoning is behind how Laravel detects if the request shouldReturnJson when handling an AuthenticationException.
You indicate you want json response by sendingAccept: application/json (not Accept */*) request header.
Here's your scenario:
Your signout route is behind auth middleware.
You're detected as guest (probably you're not sending the auth headers correctly?) and you don't want json response (the missing json Accept header). At this point Laravel redirects you to login by default.
Solution 2:[2]
Its hitting the Authenticate Middleware where by default it redirects you to route('login'). This is because when you delete the token the user doesn't have access through auth:sanctum so it redirects the Unauthenticated user to the login route that doesn't exists. Just change the redirect in Middleware/Authenticate to signin/signout route.
Change the singout() in your Controller to this
Auth::guard($this->guard())->logout();
Request::session()->invalidate();
Request::session()->regenerateToken();
This will logout the user without hitting the Authenticate Middleware, it will return a json response of 204 or No Content. NOTE: just change your set guard instead of $this->guard() I recommend adding a private function inside of your UserController so you can get the correct guard every time and that would look like this
if(isset($this->guard) && $this->guard) {
return $this->guard;
}
return config('auth.defaults.guard');
Solution 3:[3]
In headers(postman), add following key value
Accept : application/json
Solution 4:[4]
in laravel 8 after modify route file (or config files) you must use
php artisan optimize command
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | Muhammed Suhail |
| Solution 4 | MmrDev |
