Troubleshooting Issues with Laravel Tests and JWT Authentication
marcellopato opened this issue · comments
Subject of the issue
This code returns a valid Toker:
public function login(Request $request): JsonResponse
{
if (!$this->authenticateUser($request)) {
return response()->json(['message' => 'Credenciais inválidas'], 401);
}
$user = Auth::user();
if (!$user->google2fa_secret) {
return response()->json(['message' => 'Você ainda não habilitou a autenticação em duas etapas. Por favor, habilite para continuar.']);
}
return response()->json(['token' => JWTAuth::attempt($request->only('email', 'password'))]);
}
private function authenticateUser(Request $request): bool
{
return JWTAuth::attempt($request->only('email', 'password'));
}
But this test: returns 401, and I can't figure why
public function testLogin()
{
$randomBytes = random_bytes(10);
$google2faSecret = Base32::encodeUpper($randomBytes);
$user = User::factory()->create([
'name' => 'Dude',
'email' => 'dude@mail.com',
'password' => '123456',
'google2fa_secret' => $google2faSecret,
'email_verified_at' => now(),
]);
$user->assignRole('vendor');
$response = $this->actingAs($user)->json('POST', '/api/login', [
'email' => $user->email,
'password' => $user->password,
]);
$response->assertStatus(200);
$response->assertJson(['token' => $response->json('token')]);
}
Your environment
Q | A |
---|---|
Bug? | no |
New Feature? | no |
Framework | Laravel |
Framework version | 10.33.0 |
Package version | 2.0 |
PHP version | 8.2.12 |
Steps to reproduce
Works when request from Insomnia, but doesn't from php artisan test
Expected behavior
I think it should get the token
Actual behavior
The dd()
response from the authenticateUser()
is false
I forgot to say, but I do have the JWT_SECRET
generated on the .env.testing
file
Found the solution! First, added JWTAuth::from($user); as follows:
public function testLogin()
{
$randomBytes = random_bytes(10);
$google2faSecret = Base32::encodeUpper($randomBytes);
$user = User::factory()->create([
'name' => 'Ronaldo',
'email' => 'dude@mail.com.br',
'password' => '123456',
'google2fa_secret' => $google2faSecret,
'email_verified_at' => now(),
]);
$user->assignRole('vendor');
$token = JWTAuth::fromUser($user);
$response = $this->json('POST', '/api/login', [
'email' => $user->email,
'password' => $user->password,
'token' => $token,
]);
$response->assertStatus(200);
$response->assertJson(['token' => $response->json('token')]);
}
And, at the login() added a if condition:
public function login(Request $request): JsonResponse
{
if (env('APP_ENV') !== 'testing') {
if (!$this->authenticateUser($request)) {
return response()->json(['message' => 'Credenciais inválidas'], 401);
}
}
$user = Auth::user();
if (!$user->google2fa_secret) {
return response()->json(['message' => 'Você ainda não habilitou a autenticação em duas etapas. Por favor, habilite para continuar.']);
}
return response()->json(['token' => JWTAuth::attempt($request->only('email', 'password'))]);
}