When developing REST APIs, authentication is one of the important things developers need to understand.
Imagine you are building a restaurant management system using Laravel. You have endpoints for managing menu categories, menu items, products, customers, and sales.
Some endpoints are public, while others should only be accessible to authenticated users.
For example:
POST /api/login
GET /api/menu-categories
POST /api/menu-categories
PUT /api/menu-categories/1
DELETE /api/menu-categories/1
You might notice that when you try accessing a protected endpoint using Postman, Laravel returns:
{
"success": false,
"message": "Unauthenticated."
}
Why does this happen?
The endpoint requires authentication, but your request does not contain a valid authentication token.
In this article, we will learn how to authenticate with a Laravel API, automatically extract an access token from the login response, store it in Postman environment variables, and reuse it when accessing protected endpoints.
1. Understanding API Authentication
Before writing any code, let's understand what API authentication means.
API authentication is the process of verifying the identity of a client before allowing it to access protected resources.
For example, when a user logs into a restaurant management application, Laravel checks their credentials.
If the credentials are valid, the application can issue an access token.
The client then uses this token when making subsequent requests to protected endpoints.
A typical authentication workflow looks like this:
- The client sends login credentials.
- Laravel validates the credentials.
- Laravel generates an access token.
- Laravel returns the token in a JSON response.
- The client includes the token in subsequent API requests.
- Laravel validates the token before allowing access.
This is commonly implemented using Bearer Token authentication.
2. Understanding Bearer Token Authentication
A Bearer Token is an authentication credential sent in the HTTP request header.
For example:
GET /api/menu-categories HTTP/1.1
Host: localhost:8000
Accept: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
The important part is:
Authorization: Bearer YOUR_ACCESS_TOKEN
The Authorization header tells Laravel that the client is providing an authentication token.
The word Bearer identifies the authentication scheme, while YOUR_ACCESS_TOKEN represents the actual token.
Without a valid token, protected endpoints will reject the request.
3. Authenticating with Laravel
In Laravel, authentication middleware can be used to protect API routes.
For example, consider the following code in routes/api.php:
Route::middleware('auth:sanctum')->group(function () {
Route::apiResource(
'menu-categories',
MenuCategoryController::class
);
});
Let's understand what is happening.
What does auth:sanctum mean?
auth:sanctum is Laravel authentication middleware that requires a valid authenticated user.
It protects the routes inside the middleware group.
In this example, all menu category operations require authentication.
That includes:
- GET: Retrieve menu categories.
- POST: Create a menu category.
- PUT/PATCH: Update a menu category.
- DELETE: Delete a menu category.
If an unauthenticated user attempts to access these endpoints, Laravel returns an authentication error.
Important: Sanctum supports both SPA cookie-based authentication and personal access tokens. This article focuses on personal access tokens when using Postman.
4. Logging into the API Using Postman
Before accessing protected endpoints, we need to authenticate.
Assume your Laravel application has a login endpoint:
POST http://127.0.0.1:8000/api/login
In Postman:
- Select POST as the HTTP method.
- Enter your login endpoint.
- Open the Body tab.
- Select raw.
- Choose JSON.
- Provide your login credentials.
Example:
{
"email": "developer@example.com",
"password": "password123"
}
When you send the request, Laravel validates the credentials.
If authentication succeeds and your login controller issues a Sanctum personal access token, you might receive a response like this:
{
"success": true,
"message": "Login successful",
"data": {
"access_token": "eyJhbGciOiJIUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 3600
}
}
The important fields are:
| Field | Purpose |
|---|---|
| access_token | Authentication credential |
| token_type | Authentication scheme |
| expires_in | Token validity duration, if provided |
Now that we have an access token, we can use it to authenticate other requests.
However, manually copying and pasting tokens every time can become repetitive.
This is where Postman environment variables become useful.
5. Understanding Postman Environment Variables
Environment variables allow developers to store reusable values that can be accessed across multiple API requests.
For example, instead of repeatedly writing:
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
We can store the token in a variable:
access_token
Then reference it using:
{{access_token}}
This makes API testing easier because when the token changes, we only need to update the environment variable.
Postman provides a JavaScript API for managing these variables.
For example:
pm.environment.set("access_token", "YOUR_TOKEN");
This saves the token in the currently selected Postman environment.
6. Automatically Extracting the Access Token Using JavaScript
Instead of manually copying the access token from the login response, we can write a JavaScript script that extracts it automatically.
In Postman, open your login request and navigate to:
Scripts → Post-response
Add the following code:
// Parse the JSON response body
var jsonData = pm.response.json();
console.log("Full response:", jsonData);
// Check if the response has the expected structure
if (jsonData.data && jsonData.data.access_token) {
// Save the access token
pm.environment.set(
"access_token",
jsonData.data.access_token
);
console.log("Access token saved successfully");
// Save token type
pm.environment.set(
"token_type",
jsonData.data.token_type || "Bearer"
);
// Save token expiration duration
pm.environment.set(
"expires_in",
jsonData.data.expires_in || 3600
);
} else {
console.log("No access token found in response");
pm.expect.fail("Access token not found in response");
}
Let's break down the important parts.
A. Reading the API response
var jsonData = pm.response.json();
pm.response.json() reads the API response and converts the JSON body into a JavaScript object.
For example, if Laravel returns:
{
"data": {
"access_token": "abc123",
"token_type": "Bearer"
}
}
We can access the token using:
jsonData.data.access_token
B. Checking whether the token exists
if (jsonData.data && jsonData.data.access_token) {
This condition checks whether the response contains a data object and an access_token.
The && operator means both conditions must be true.
This prevents the script from trying to access a missing property when login fails.
C. Saving the token
pm.environment.set(
"access_token",
jsonData.data.access_token
);
This is where the token is saved.
The first argument is the environment variable name.
The second argument is the value being stored.
In this case:
Variable: access_token
Value: abc123
D. Saving the token type
pm.environment.set(
"token_type",
jsonData.data.token_type || "Bearer"
);
This saves the authentication scheme.
The || operator provides a fallback value.
If the API response does not contain token_type, Postman uses Bearer as the default.
E. Saving the expiration duration
pm.environment.set(
"expires_in",
jsonData.data.expires_in || 3600
);
This saves the token's validity duration when the API provides it.
For example:
expires_in = 3600
This represents 3,600 seconds, equivalent to one hour.
Note that storing the expiration duration does not automatically refresh the token when it expires.
7. Reusing the Access Token in Other API Requests
Now comes the interesting part.
We have successfully saved the access token in Postman's environment variables.
Let's use it to access our protected menu category endpoint.
For example:
GET http://127.0.0.1:8000/api/menu-categories
In Postman:
- Open the menu categories request.
- Navigate to the Authorization tab.
- Select Bearer Token as the authentication type.
- Enter the following variable:
{{access_token}}
Postman automatically retrieves the saved token and attaches it to the request.
Alternatively, you can add the following headers manually:
Accept: application/json
Authorization: Bearer {{access_token}}
When the request is sent, Laravel receives the token and checks whether it is valid.
If authentication succeeds, the controller executes and returns the menu categories.
8. Understanding the Complete Authentication Workflow
Let's bring everything together.
The following diagram illustrates how Laravel and Postman work together:
flowchart TD
A["Send POST login request"] --> B["Laravel validates credentials"]
B --> C["Laravel generates access token"]
C --> D["Laravel returns JSON response"]
D --> E["Postman reads JSON response"]
E --> F["JavaScript extracts access_token"]
F --> G["Save token in environment variable"]
G --> H["Send GET menu-categories request"]
H --> I["Postman attaches Bearer token"]
I --> J["Laravel validates token using Sanctum"]
J --> K["Return menu categories"]
This workflow eliminates the need to manually copy authentication tokens every time you test an endpoint.
9. Common Problems Developers Encounter
While implementing API authentication, you might encounter some common problems.
Problem 1: Unauthenticated error
Response:
{
"success": false,
"message": "Unauthenticated."
}
Possible causes:
- You did not provide an authentication token.
- The token is invalid.
- The token has been revoked.
- The token has expired, if expiration is configured.
- You are using the wrong authentication mechanism.
Solution: Check your Authorization header and ensure that Postman is sending a valid token.
Problem 2: Access token not found
Your Postman Console might display:
No access token found in response
This could happen because your login response has a different JSON structure.
For example, your API might return:
{
"access_token": "abc123"
}
Instead of:
{
"data": {
"access_token": "abc123"
}
}
You must adjust your JavaScript to match the actual API response structure.
Problem 3: Token saved but authentication still fails
Saving a token in Postman does not automatically make it valid.
For Laravel Sanctum, ensure your login controller generates a personal access token correctly.
For example:
$token = $user->createToken('postman-token')->plainTextToken;
The createToken() method requires the Sanctum HasApiTokens trait on your User model.
You should also ensure that your Postman request uses:
Authorization: Bearer YOUR_ACCESS_TOKEN
Problem 4: Wrong Postman environment selected
Postman environment variables belong to the selected environment.
If you save the token in one environment but send requests using another, the variable might not be available.
Check the active environment before testing your endpoints.
10. Best Practices When Working with API Tokens
As developers, we should follow good security practices when handling authentication credentials.
- Never hardcode tokens: Store reusable credentials in environment variables.
- Avoid exposing tokens: Do not publish real access tokens in GitHub repositories, screenshots, or public documentation.
- Use HTTPS: Protect authentication credentials when communicating with production APIs.
- Handle expired tokens: Implement an appropriate reauthentication or token renewal strategy.
- Validate authentication on the backend: Never assume that a request is authenticated simply because it contains a token.
- Use separate environments: Keep development, staging, and production configurations separate.
Conclusion
Automating API authentication in Postman makes backend development and API testing much easier.
By combining Laravel authentication middleware, Bearer Tokens, Postman environment variables, and JavaScript scripts, developers can automatically retrieve and reuse authentication tokens across multiple API requests.
The most important concepts to remember are:
- Laravel middleware protects API endpoints.
- Bearer Tokens provide authentication credentials.
- Postman JavaScript can extract values from API responses.
- Environment variables allow us to reuse those values.
-
{{access_token}}makes the saved token available across requests.
Once you understand this workflow, testing protected REST API endpoints becomes much more efficient, especially when developing larger applications with multiple API resources.
Keep building, keep testing, and keep learning!
Top comments (0)