Skip to main content
The AuthStore is an Angular service that manages authentication state using Angular signals. It stores the user access token, user information, and provides computed properties for authentication status.

Overview

This injectable service uses Angular’s signal API to provide reactive authentication state management. The state is automatically persisted to localStorage and restored on application restart. Source: src/app/shared/services/state/auth.store.ts

Computed properties

All properties are reactive signals that automatically update when the authentication state changes.

userId

userId: Signal<number>
userId
Signal<number>
required
Signal containing the current user’s ID

user

user: Signal<User>
user
Signal<User>
required
Signal containing the current user object with all user properties

accessToken

accessToken: Signal<string>
accessToken
Signal<string>
required
Signal containing the current user’s access token. Empty string if not authenticated.

isAuthenticated

isAuthenticated: Signal<boolean>
isAuthenticated
Signal<boolean>
required
Signal that returns true if the user has an access token (authenticated), false otherwise

isAnonymous

isAnonymous: Signal<boolean>
isAnonymous
Signal<boolean>
required
Signal that returns true if the user does not have an access token (anonymous), false otherwise

Methods

setState()

setState(userAccessToken: UserAccessToken): void
Saves the new authentication state and persists it to localStorage.
userAccessToken
UserAccessToken
required
The new authentication state containing the user object and access token
Behavior:
  • Updates the internal signal state
  • Automatically saves to localStorage using the userAccessToken key
  • Triggers all computed properties to update
return
void
No return value

Usage example

Basic authentication flow

import { Component, inject, Signal } from '@angular/core';
import { AuthStore } from '@services/state/auth.store';
import { UserAccessToken } from '@domain/userAccessToken.type';

@Component({
  selector: 'app-login',
  template: `
    @if (authStore.isAuthenticated()) {
      <p>Welcome, User ID: {{ authStore.userId() }}</p>
      <button (click)="logout()">Logout</button>
    } @else {
      <button (click)="login()">Login</button>
    }
  `
})
export class LoginComponent {
  authStore = inject(AuthStore);

  login() {
    // After successful authentication
    const userAccessToken: UserAccessToken = {
      user: { id: 123, name: 'John Doe', email: '[email protected]' },
      accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
    };
    
    this.authStore.setState(userAccessToken);
  }

  logout() {
    const nullToken: UserAccessToken = {
      user: { id: 0, name: '', email: '' },
      accessToken: ''
    };
    
    this.authStore.setState(nullToken);
  }
}

Using computed signals in templates

import { Component, inject } from '@angular/core';
import { AuthStore } from '@services/state/auth.store';

@Component({
  selector: 'app-header',
  template: `
    <header>
      @if (authStore.isAuthenticated()) {
        <span>{{ authStore.user().name }}</span>
        <span>Token: {{ authStore.accessToken().substring(0, 10) }}...</span>
      } @else {
        <span>Anonymous User</span>
      }
    </header>
  `
})
export class HeaderComponent {
  authStore = inject(AuthStore);
}

Checking authentication status

import { inject } from '@angular/core';
import { Router } from '@angular/router';
import { AuthStore } from '@services/state/auth.store';

export const authGuard = () => {
  const authStore = inject(AuthStore);
  const router = inject(Router);

  if (authStore.isAuthenticated()) {
    return true;
  }

  return router.parseUrl('/login');
};

State persistence

The authentication state is automatically:
  • Saved to localStorage when setState() is called
  • Restored from localStorage when the service is initialized
  • Stored under the key userAccessToken
If no state exists in localStorage, the store initializes with NULL_USER_ACCESS_TOKEN.

Build docs developers (and LLMs) love