Laravel Sanctum (Airlock) with Postman

I'm really excited to be using Laravel Sanctum, but once I fired up Postman to start testing my endpoint responses, I realised this would take a little more work than just attaching a token (unless you're using token based authentication with Sanctum).

If you're building a SPA and want to test out your endpoints with cookie-based authentication in Postman, here's how.

The jist of it

Because Sanctum uses cookie-based authentication and hits CSRF protected endpoints like /login and /logout, we need to make sure we're sending a CSRF token with Postman. We get this by sending a request to /sanctum/csrf-cookie first. We'll also need to make sure the Referrer is properly sent for future requests for Sanctum to allow them.

I'm testing this with a Laravel Project properly configured with Sanctum, that allows requests from localhost, in terms of both CORS and Sanctum domains.

Create a Postman Collection

To make this as effortless as possible, I'd recommend creating a Postman collection so we can apply our pre-request script (in a moment) to all endpoints.

I'm calling this Forum, because I'm using the API I already have set up for a Nuxt/Laravel forum course.

Once the collection is created, this makes it easier to apply a pre-request script to all endpoints under that collection. It also helps keep everything nice and tidy.

Create an environment

We're going to be setting a CSRF token in our environment variables in Postman, so we need to create a Postman environment.

Click the cog in the top right of Postman, click Add and give your environment a name (mine's forum). Click Add again and switch to your environment in the top right (see top right of screenshot).

Add a pre-request script

Just before we do that, create a new request to /login in Postman, save it to your collection and add in the form data (email and password). Add an Accept header with application/json too, so you get back JSON.

Now make another request to /login. This time, the pre-request script will be run and will set the cookie we get back from the /sanctum/csrf-cookie endpoint into our environment.

Hit the eye icon in the top right to check.

Great, that's our CSRF token value.

Now update the /login request to add the X-XSRF-TOKEN header with the value {{xsrf-token}} (this is the value of our environment variable), and send the request again.

Make sure you don't include spaces between the curly braces (e.g. {{ xsrf-token }}). Postman doesn't like that.

Hopefully that worked for you. If not, you may have to check your Sanctum setup.

Make authenticated requests

So we've sorted CSRF, now we'll make a request to /api/user to verify we're actually authenticated. Create a request for this in Postman and add it to your collection. And of course, send that request.

Hmm, unauthenticated.

Now, this should actually work. Postman has stored the cookies we got back from making the earlier request to /login and will send them along with this request. You can verify this by clicking the cookies link to the top right of your request.

The reason this isn't working is that Sanctum is denying the authenticated request based on the referrer.

If you're interested in diving into some Sanctum code and figuring out why, open up theEnsureFrontendRequestsAreStateful middleware and check out the fromFrontend method that all requests are piped through.