How to store tokens securely in Angular

Storing authentication tokens securely is critical for preventing XSS attacks and unauthorized access. As the creator of CoreUI with 12 years of Angular development experience, I’ve implemented token storage strategies for enterprise applications handling sensitive financial and healthcare data.

The most secure approach is to use httpOnly cookies for storage and avoid localStorage entirely for sensitive tokens.

Best Practice: HttpOnly Cookies

Configure your backend to send tokens in httpOnly cookies:

// Backend (Node.js/Express example)
res.cookie('auth_token', token, {
  httpOnly: true,
  secure: true,
  sameSite: 'strict',
  maxAge: 3600000
})

Angular automatically includes cookies in requests. Configure HttpClient:

import { HttpClient } from '@angular/common/http'
import { Injectable } from '@angular/core'

@Injectable({
  providedIn: 'root'
})
export class ApiService {
  constructor(private http: HttpClient) {}

  getData() {
    return this.http.get('/api/data', {
      withCredentials: true
    })
  }
}

Alternative: Memory Storage with Refresh Tokens

If you must handle tokens client-side, store access tokens in memory and refresh tokens in httpOnly cookies:

import { Injectable } from '@angular/core'
import { BehaviorSubject, Observable } from 'rxjs'

interface TokenPair {
  accessToken: string
  expiresAt: number
}

@Injectable({
  providedIn: 'root'
})
export class TokenService {
  private tokenSubject = new BehaviorSubject<string | null>(null)
  private tokenExpiry: number | null = null

  get token$(): Observable<string | null> {
    return this.tokenSubject.asObservable()
  }

  get accessToken(): string | null {
    if (this.isTokenExpired()) {
      return null
    }
    return this.tokenSubject.value
  }

  setTokens(accessToken: string, expiresIn: number): void {
    this.tokenSubject.next(accessToken)
    this.tokenExpiry = Date.now() + expiresIn * 1000
  }

  clearTokens(): void {
    this.tokenSubject.next(null)
    this.tokenExpiry = null
  }

  private isTokenExpired(): boolean {
    if (!this.tokenExpiry) return true
    return Date.now() >= this.tokenExpiry
  }
}

HTTP Interceptor

Add tokens to requests automatically:

import { Injectable } from '@angular/core'
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http'
import { Observable } from 'rxjs'
import { TokenService } from './token.service'

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor(private tokenService: TokenService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const token = this.tokenService.accessToken

    if (token) {
      const cloned = req.clone({
        setHeaders: {
          Authorization: `Bearer ${token}`
        }
      })
      return next.handle(cloned)
    }

    return next.handle(req)
  }
}

Register the interceptor:

import { HTTP_INTERCEPTORS } from '@angular/common/http'

export const appConfig: ApplicationConfig = {
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptor,
      multi: true
    }
  ]
}

Security Comparison

Never use localStorage for sensitive tokens:

  • ❌ Vulnerable to XSS attacks
  • ❌ Accessible by any JavaScript code
  • ❌ No expiration mechanism

HttpOnly cookies (recommended):

  • ✅ Not accessible via JavaScript
  • ✅ Automatic expiration
  • ✅ CSRF protection with SameSite

Memory storage (acceptable):

  • ✅ Cleared on page refresh
  • ✅ Not vulnerable to XSS theft
  • ⚠️ Requires refresh token strategy

Best Practice Note

This is the same token storage strategy we use in CoreUI’s Angular admin templates for maximum security. HttpOnly cookies provide the best protection against XSS attacks, which are the most common web vulnerability.

For production applications, consider using CoreUI’s Angular Admin Template which includes pre-built secure authentication with httpOnly cookie support and automatic token refresh.

If you’re implementing authentication, you might also want to learn how to refresh JWT tokens in Angular to maintain user sessions securely.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to force a React component to re-render
How to force a React component to re-render

What are the three dots `...` in JavaScript do?
What are the three dots `...` in JavaScript do?

How to Use Bootstrap Modal in Vue 3 – Clean Integration with CoreUI
How to Use Bootstrap Modal in Vue 3 – Clean Integration with CoreUI

What Does javascript:void(0) Mean?
What Does javascript:void(0) Mean?

Answers by CoreUI Core Team