vincent15000's avatar

API authentication test

Hello,

Here is my VueJS code.

axios.get('/sanctum/csrf-cookie').then(response => {
    axios.post('/login', {
        email: user.email,
        password: user.password
    }).then(response => {
        this.isAuthenticated();
    });
});

I'm using Fortify to authenticate.

I'm trying to write a test to authenticate.

$response = $this->get('/sanctum/csrf-cookie');
$response->assertStatus(204); // here I get 204

$response = $this->postJson('/login', [
    'email' => '[email protected]',
    'password' => 'password',
]);
$response->assertStatus(200); // here I get 500

What am I doing wrong ?

Thanks for your help.

V

0 likes
5 replies
LaryAI's avatar
Level 58

Hello V,

It looks like you're trying to test your authentication flow using Laravel Sanctum with Fortify. Your VueJS code seems correct for the frontend part, but let's focus on the test that is failing.

The 500 status code you're receiving indicates there's a server error when you attempt to log in. This could be due to a variety of reasons, such as a misconfiguration in your testing environment, an issue with the user credentials, or an error within your authentication logic.

Here's a step-by-step guide to help you troubleshoot and write a test for your authentication:

  1. Ensure your testing environment is set up correctly. Check your .env.testing file to make sure it's configured to use a test database and that your test database is migrated.

  2. Make sure you have a user in your test database with the email '[email protected]' and the password 'password'. You can create this user in your test setup:

use App\Models\User;
use Illuminate\Support\Facades\Hash;

// ...

public function setUp(): void
{
    parent::setUp();
    // Create a user for the test
    User::create([
        'name' => 'Test User',
        'email' => '[email protected]',
        'password' => Hash::make('password'),
    ]);
}
  1. Write the test to make the CSRF and login requests. Here's an example of how you might write the test:
public function test_user_can_authenticate()
{
    // Get CSRF token
    $response = $this->get('/sanctum/csrf-cookie');
    $response->assertStatus(204);

    // Attempt to log in
    $response = $this->postJson('/login', [
        'email' => '[email protected]',
        'password' => 'password',
    ]);

    // Check if the login was successful and the status is 200 or 204
    $response->assertStatus(200); // or $response->assertStatus(204) if no content is returned

    // Optionally, check if the user is authenticated
    $this->assertAuthenticated();
}
  1. If you're still getting a 500 error, check your Laravel logs (usually found in storage/logs/laravel.log) for more details on the error. This will give you a clue as to what's going wrong.

  2. If the error is related to the Sanctum configuration, make sure you have followed all the Sanctum installation steps, including updating your config/sanctum.php, config/cors.php, and any middleware settings.

  3. If the error is related to Fortify, ensure that you have published and properly configured the Fortify service provider and its components.

By following these steps, you should be able to identify the issue and successfully test your API authentication. Remember to always check the logs for detailed error messages when you encounter a 500 status code.

martinbean's avatar
Level 80

@vincent15000 You shouldn’t be making multiple HTTP requests inside a single test case like that. The framework is booted in between requests and will lead to unintentional behaviour due to state leaking across requests.

1 like
vincent15000's avatar

@martinbean Ok I understand.

Hmmm ... what I just noticed is that the test is succesful even I don't request for the CSRF cookie.

Is that normal ?

vincent15000's avatar

@martinbean The problem was simply that I forgot to migrate the test database.

But thank you for the remark about the multiple requests in one test, I have updated my code according to that.

gych's avatar

@vincent15000

For tests the application doesn't boot between each request, the application is only booted once per test.

So when you use multiple requests in a test, the application will not boot for each request. Therefore using multiple requests in a test can cause unexpected behavior. Your test might pass but it can be misleading because it doesn't reflect how your app works outside of the testing environment.

So like @martinbean already said, avoid multiple HTTP requests in a test

Its also metioned in the Laravel docs https://laravel.com/docs/11.x/http-tests#making-requests

In general, each of your tests should only make one request to your application. Unexpected behavior may occur if multiple requests are executed within a single test method.

2 likes

Please or to participate in this conversation.