Follow-up question to this question: Why is my authenticated-user route coming back not authenticated?
I'm building a Laravel API using JWT token for authentication. I'm sending the token as a HTTPOnly cookie. When I set the cookie name as authToken
, then run login
and then authenticate_user
in Postman, it shows user not authenticated
. When I change the cookie name to just token
, then rerun the postman tests, authenticate_user
returns true with the user data. Does the cookie need to be a specific name? Why does token
work but authToken
did not? Is this a rule swt by Tymon/jwt-auth
?
Here’s the relevant part of my login function:
/**
* Get the authenticated User.
*
* @return \Illuminate\Http\JsonResponse
*/
public function authenticate_user()
{
$user = auth()->user();
if(!$user) {
return response()->json([
"message" => "User not authenticated."
], 401);
}
$roles = $user->getRoleNames();
$permissions = $user->getAllPermissions();
return response()->json([
'isAuthenticated' => true,
"user" => $user,
'roles' => $roles,
'permissions' => $permissions->pluck('name')
], 200);
}
/**
* Get a JWT via given credentials.
*
* @return \Illuminate\Http\JsonResponse
*/
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if (! $token = auth()->attempt($credentials)) {
return response()->json([
"message" => "Error logging in: Invalid credentials."
], 401);
}
// Set the JWT token in an HttpOnly cookie
return response()->json([
"message" => "Login successful!"
], 200)->cookie('token', $token, auth()->factory()->getTTL() * 60, '/', null, true, true, false, 'Strict'); // Change from authToken
}
Whys does token
work, but authToken
does not? Is there a specific naming convention that allows the token to be automatically recognized from Laravel to React and vice versa?
tymon/jwt-auth
expects the cookie to be named token
.
This library uses a concept of parsers, where a parser tries to get the authentication from an incoming request. There is a few of them.
One of them is Tymon\JWTAuth\Http\Parser\Cookies, handling cookie authentication. key
property comes from Tymon\JWTAuth\Http\Parser\KeyTrait. The default value is token
(being the cookie name), corresponding to what you observed. You can use setKey
method to change this value.
The easiest way to change the cookie name is to add a new parser to the parsing chain. You can do that by creating your own service provider, extending Tymon\JWTAuth\Providers\LaravelServiceProvider
. You can either add it or set it to be the only one available, making cookies the only way to be authenticated.
<?php
namespace App\Providers;
use Tymon\JWTAuth\Http\Parser\Cookies;
use Tymon\JWTAuth\Providers\LaravelServiceProvider;
class TymonServiceProvider extends LaravelServiceProvider
{
public function boot()
{
parent::boot();
$cookieName = 'authToken';
$parser = new Cookies($this->config('decrypt_cookies'));
$parser->setKey($cookieName);
// to add a new parser
$this->app['tymon.jwt.parser']->addParser($parser);
// // to only use this parser
// $this->app['tymon.jwt.parser']->setChain([
// $parser,
// ]);
}
}
Don't forget to register this provider instead of the original one (in bootstrap/providers.php
for Laravel 11).