Where to Store the Token

Options

WhereSurvives refresh?Readable by JavaScript (XSS risk)?Sent automatically (CSRF risk)?
React state / memoryNoOnly your code, while the page is openNo
localStorageYesYes: any injected script can steal itNo
sessionStorageOnly in that tabYesNo
HttpOnly cookieYesNoYes: needs SameSite + CSRF protection

What ShopEase Does

  • Step 1 (this module): keep the access token in localStorage. It is simple and very common. Its risk is XSS: if an attacker runs JavaScript on your page, they can read it. Short expiry (15 min) limits the damage.
  • Step 2 (Refresh Tokens module): keep the access token only in memory and put a long-lived refresh token in an HttpOnly cookie. JavaScript cannot read the cookie, and a page reload gets a fresh access token from it. This is the recommended setup for production.
// src/api.js (part 1: token storage)
const TOKEN_KEY = 'shopease_token';
const USER_KEY = 'shopease_user';

export const tokenStore = {
  get: () => localStorage.getItem(TOKEN_KEY),
  getUser: () => JSON.parse(localStorage.getItem(USER_KEY) || 'null'),
  save(token, user) {
    localStorage.setItem(TOKEN_KEY, token);
    localStorage.setItem(USER_KEY, JSON.stringify(user));
  },
  clear() {
    localStorage.removeItem(TOKEN_KEY);
    localStorage.removeItem(USER_KEY);
  },
};

Note

Note: Whatever you choose, the best protection against token theft is preventing XSS: React escapes text by default, so avoid dangerouslySetInnerHTML with user content, and add a Content-Security-Policy header.