Reputation: 4616
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']);
});
I get the error when I access https://mysite.test/api/signout
in Postman.
Route [login] not defined.
Upvotes: 2
Views: 2046
Reputation: 31
in laravel 8 after modify route file (or config files) you must use
php artisan optimize
command
Upvotes: 0
Reputation: 2644
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 sending
Accept: 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.
Upvotes: 3
Reputation: 289
In headers(postman), add following key value
Accept : application/json
Upvotes: 2
Reputation: 1021
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');
Upvotes: 1