Authentication

Almost every real API restricts write operations — and often reads too — to authenticated callers. RecipeBox is no different: creating, updating, or deleting a recipe requires proving who you are first. Postman supports the three authentication styles you'll run into constantly: Basic Auth, Bearer Tokens, and API Keys. This lesson works through a full RecipeBox login flow and wires the resulting token into every other request in the collection.

Three Common Authentication Styles

StyleHow credentials travelTypical use
Basic Auth Username and password, base64-encoded, in an Authorization: Basic <encoded> header Simple internal tools; not something you'd want over plain HTTP since base64 isn't encryption
Bearer Token A token (often a JWT) obtained by logging in, sent as Authorization: Bearer <token> The most common style for modern REST APIs — this is how RecipeBox itself works
API Key A static key sent either as a header (e.g. X-API-Key) or a query parameter (e.g. ?apiKey=...) Server-to-server integrations and public API tiers, often paired with rate limiting

Step 1: Logging In to Get a Token

The Login request in the Auth folder sends RecipeBox credentials to get a token back:

POST {{baseUrl}}/auth/login
Content-Type: application/json

{
  "username": "tester@recipebox.example.com",
  "password": "P@ssw0rd123"
}

// Response — 200 OK
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expiresIn": 3600
}

In the Login request's Tests tab, save that token so every later request can read it:

var jsonData = pm.response.json();

pm.test("login succeeded and returned a token", function () {
  pm.response.to.have.status(200);
  pm.expect(jsonData).to.have.property("token");
});

pm.collectionVariables.set("token", jsonData.token);

This is the same pm.collectionVariables.set() pattern from the chaining lesson — logging in is really just another form of chaining, where the value being passed forward happens to be a token instead of a resource id.

Step 2: Using the Token — Two Ways

Option A: Postman's Auth Tab (Recommended)

  1. Open Create Recipe (or any protected request) and click its Authorization tab.
  2. Set Type to Bearer Token.
  3. In the Token field, enter {{token}}.

Postman builds the Authorization: Bearer {{token}} header for you at send-time. Better still, set this once at the collection level (RecipeBox API → Authorization tab → Bearer Token → {{token}}) and every request that "inherits auth from parent" picks it up automatically — no need to configure it request-by-request.

Option B: Setting the Header Manually

Functionally identical, done by hand on the Headers tab (or via a pre-request script, as shown last lesson):

Authorization: Bearer {{token}}

Both options send the exact same header over the wire. The Auth tab exists because remembering to type Bearer correctly and re-adding the header to every new request gets tedious and error-prone — but understanding the manual version matters, since it's what the Auth tab is doing for you under the hood, and it's the only option when a token needs extra processing a plain field can't do.

Basic Auth and API Key in Postman's Auth Tab

The same Authorization tab handles the other two styles without any manual header work:

TypeFields Postman asks forHeader it builds
Basic AuthUsername, PasswordAuthorization: Basic <base64(username:password)>
API KeyKey, Value, Add to (Header or Query Params)X-API-Key: <value> (or appended as a query string param)
Bearer TokenTokenAuthorization: Bearer <value>

Verifying Auth Actually Works

Don't just assume the header is being sent correctly — assert against both the success and failure paths:

pm.test("authenticated request succeeds", function () {
  pm.response.to.have.status(201);
});

// On a separate request sent with no token / a bad token:
pm.test("unauthenticated request is rejected", function () {
  pm.response.to.have.status(401);
});

That second assertion matters as much as the first — an API that silently accepts requests with no valid token at all is a security bug, and it's exactly the kind of thing API-level testing catches that clicking through a UI never would.

Note: Never hardcode real credentials or tokens directly into a request body or shared collection. Keep password and token in environment variables (ideally marked as secret type in Postman) so they aren't accidentally committed or shared when the collection is exported.
Next: You can now authenticate and check individual fields, but larger responses need a more scalable check than one pm.expect() per field. JSON Schema Validation covers validating a whole Recipe object's shape in a single assertion.