Sending the Token with Axios

An Axios Instance with Interceptors

An interceptor runs for every request or response. The request interceptor adds the header; the response interceptor reacts to 401 (token missing or expired) by logging the user out.

// src/api.js (part 2)
import axios from 'axios';

export const api = axios.create({
  baseURL: import.meta.env.VITE_API_URL || 'http://localhost:8080/api',
});

api.interceptors.request.use((config) => {
  const token = tokenStore.get();
  if (token) {
    config.headers.Authorization = 'Bearer ' + token;
  }
  return config;
});

api.interceptors.response.use(
  (response) => response,
  (error) => {
    const status = error.response?.status;
    const isLogin = error.config?.url?.includes('/auth/login');
    if (status === 401 && !isLogin) {
      tokenStore.clear();
      window.location.assign('/login?expired=1');
    }
    return Promise.reject(error);
  },
);

Using It in a Page

// src/pages/OrdersPage.jsx
import { useEffect, useState } from 'react';
import { api } from '../api';

export default function OrdersPage() {
  const [orders, setOrders] = useState([]);
  const [error, setError] = useState('');

  useEffect(() => {
    api.get('/orders')
      .then((res) => setOrders(res.data))
      .catch((err) => {
        if (err.response?.status === 403) setError('You are not allowed to see these orders.');
      });
  }, []);

  if (error) return <p className="error">{error}</p>;
  return (
    <ul>
      {orders.map((o) => (
        <li key={o.id}>#{o.id} - {o.status} - Rs {o.total}</li>
      ))}
    </ul>
  );
}

Request

What the browser sends (DevTools → Network):

GET /api/orders HTTP/1.1
Host: localhost:8080
Origin: http://localhost:5173
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhc2hhQHNob3BlYXNlLmluIi...

Example output

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost:5173
Content-Type: application/json
[{"id":1001,"status":"SHIPPED","total":2998.0},{"id":1004,"status":"PLACED","total":649.0}]

Tip

Tip: With fetch instead of axios, write a small wrapper: fetch(url, { ...options, headers: { ...options.headers, Authorization: 'Bearer ' + token } }) and check res.status === 401 yourself. Never put the token in the URL (?token=...): URLs end up in server logs and browser history.