Learn how to rigorously secure your endpoints by testing Sanctum authentication. Master asserting unauthorized codes, token validation, and user mocking.
Previously in this course, we covered the basics of Feature Testing Fundamentals: Automating Laravel API Verification. While those lessons established how to assert JSON responses, they often assumed an open environment. In this lesson, we add the crucial layer of security verification: ensuring your API endpoints are correctly guarded.
When we build APIs, our security relies on the assumption that an endpoint is inaccessible unless a valid identity is provided. In Laravel, when using Mastering REST API Authentication with Laravel Sanctum, we aren't just testing if the code runs; we are testing the middleware layer.
Testing authentication involves three distinct scenarios:
401 Unauthorized status code.Before testing success, always test failure. If your endpoint doesn't return a 401 for guest users, your security layer is misconfigured.
PHP#6A9955">/** @test */ public function it_denies_access_to_unauthenticated_users() { #6A9955">// We send a request to a protected route without any headers $response = $this->getJson('/api/v1/projects'); #6A9955">// Assert that the API rejects the request $response->assertStatus(401); }
This test ensures that your auth:sanctum middleware is correctly applied to the route group. If this test fails, you have an unprotected route, regardless of how robust your logic is.
To test that a real token works, we need to create a user and issue a token via Sanctum's createToken method. This is a functional test that verifies the entire integration between the database and the authentication guard.
PHP#6A9955">/** @test */ public function it_allows_access_to_authenticated_users_with_valid_token() { $user = User::factory()->create(); $token = $user->createToken('test-token')->plainTextToken; $response = $this->withHeader('Authorization', 'Bearer ' . $token) ->getJson('/api/v1/projects'); $response->assertStatus(200); }
Using withHeader directly is the most explicit way to test the integration. It ensures that the Authorization header is being correctly parsed by the Sanctum guard.
In larger test suites, creating tokens for every single request can become a performance bottleneck. Laravel provides a helper to "act as" a specific user, which bypasses the token verification process entirely. This is ideal for testing authorization logic (like policies) in isolation.
PHP#6A9955">/** @test */ public function it_can_access_projects_as_a_specific_user() { $user = User::factory()->create(); #6A9955">// Use actingAs to simulate an already-authenticated state $response = $this->actingAs($user, 'sanctum') ->getJson('/api/v1/projects'); $response->assertStatus(200); }
By passing 'sanctum' as the second argument, you tell Laravel to use the Sanctum guard for this user instance. This is cleaner and faster than manual token generation when you are testing business rules rather than the authentication mechanism itself.
401 status when requesting that route without a token.actingAs($user, 'sanctum') to verify that the same route returns a 200 status for an authenticated user.setUp method or a custom trait.actingAs, always remember to pass 'sanctum' as the second argument. If omitted, Laravel defaults to the web guard, which will fail if your API routes aren't configured to use session authentication.RefreshDatabase, ensure your factories are defined correctly, otherwise, your authentication tests might fail due to missing user records.actingAs if you are specifically testing that your authentication middleware works. Use the header-based approach for verifying the security layer, and actingAs for verifying business logic.Testing API authentication is about verifying the boundary between public and private data. We use assertStatus(401) to ensure gateways are locked, withHeader to verify the full token integration, and actingAs to efficiently test authorized workflows. By mastering these three patterns, you ensure your API remains secure as it grows.
Up next: We will dive into Job Chaining and Batching to handle multi-step background processes for our project board.
Master testing events and jobs in Laravel using Event::fake() and Queue::fake(). Learn to verify background task dispatching without triggering side effects.
Read moreLearn to secure your Laravel API by mastering CORS, implementing CSRF protection for SPAs, and managing sensitive headers to prevent common web attacks.
Testing API Authentication