Securing API Requests with Bearer Tokens in Axios

Securing API Requests with Bearer Tokens in Axios

Many modern APIs utilize bearer tokens for authentication and authorization. This tutorial will guide you through the process of correctly including a bearer token in your API requests using the popular JavaScript library, Axios. We’ll cover different methods to achieve this, ranging from simple request-specific configurations to more advanced, application-wide approaches using interceptors.

What is a Bearer Token?

A bearer token is a type of access token used in the OAuth 2.0 framework. It essentially acts as a digital key that proves an application has permission to access certain resources on a server. When included in an API request, it tells the server that the request is authorized.

Including the Bearer Token in Axios Requests

Axios provides several ways to include the bearer token in your requests. Let’s explore them:

1. Request-Specific Configuration

The most straightforward approach is to include the Authorization header directly in the configuration object for each request.

import axios from 'axios';

function makeApiRequest(token) {
  const config = {
    headers: {
      'Authorization': `Bearer ${token}`
    }
  };

  axios.post('http://localhost:8000/api/v1/get_token_payloads', {}, config) // The second parameter is the request body (data)
    .then(response => {
      console.log(response);
    })
    .catch(error => {
      console.error(error);
    });
}

// Example usage:
const myToken = 'your_valid_token';
makeApiRequest(myToken);

Important: Note the order of parameters in axios.post. The first parameter is the URL, the second is the request body (data), and the third is the configuration object, which can include headers.

2. Setting Default Headers with axios.defaults

If you need to include the bearer token in every request your application makes, you can set default headers using axios.defaults.

import axios from 'axios';

const token = 'your_valid_token';

axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;

// Now, every request made with axios will automatically include the Authorization header

axios.get('/some/api/endpoint')
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.error(error);
  });

This approach is convenient, but it makes your token hardcoded within your application code. For sensitive applications, consider storing the token securely (e.g., in browser storage or a secure configuration file) and retrieving it when setting the default header.

3. Creating an Axios Instance with a Default Configuration

You can create a custom Axios instance with a predefined configuration. This approach offers a good balance between flexibility and reusability.

import axios from 'axios';

const token = 'your_valid_token';

const api = axios.create({
  baseURL: 'http://localhost:8000/api/v1', // Optional:  Set a base URL
  headers: {
    'Authorization': `Bearer ${token}`
  }
});

// Now, use 'api' to make requests:
api.get('/get_token_payloads')
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.error(error);
  });

4. Using Axios Interceptors

Axios interceptors provide a powerful way to intercept requests or responses before they are handled. This is particularly useful for adding authentication headers dynamically.

import axios from 'axios';

const service = axios.create({
  timeout: 20000 // Request timeout
});

// Request interceptor
service.interceptors.request.use(
  config => {
    // Do something before request is sent
    const token = localStorage.getItem('authToken'); // Or retrieve from a more secure source
    if (token) {
      config.headers['Authorization'] = `Bearer ${token}`;
    }
    return config;
  },
  error => {
    Promise.reject(error);
  }
);

// Example usage:
service.get('/some/api/endpoint')
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.error(error);
  });

Interceptors are highly recommended for complex applications as they allow you to centralize authentication logic and handle token refresh automatically.

Best Practices

  • Secure Token Storage: Never hardcode tokens directly into your source code. Store them securely (e.g., using browser local storage, cookies with appropriate security flags, or a dedicated authentication service).
  • Token Refresh: Implement a mechanism to refresh expired tokens automatically using a refresh token, to avoid user intervention.
  • Error Handling: Handle API errors gracefully. Check for unauthorized errors (e.g., 401 status code) and redirect the user to the login page if necessary.
  • Consider a Dedicated Authentication Library: For complex authentication scenarios, consider using a dedicated authentication library or service to simplify the process and improve security.

Leave a Reply

Your email address will not be published. Required fields are marked *