angular-standard-auth-jwt
v1.0.4
Published
Angular JWT authentication library with optional refresh token support
Maintainers
Readme
angular-standard-auth-jwt
English Documentation
Modern Angular library for JWT authentication with optional refresh token support, Angular Signals, Standalone APIs and automatic interceptors.
Requirements
- Angular 20+
- RxJS 7+
- TypeScript 5+
Installation
npm install angular-standard-auth-jwtInitial Setup
Register the library in your app.config.ts using provideAuth() and the interceptors you need:
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { provideRouter } from '@angular/router';
import {
provideAuth,
jwtInterceptor,
refreshTokenInterceptor,
} from 'angular-standard-auth-jwt';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideHttpClient(
withInterceptors([jwtInterceptor, refreshTokenInterceptor])
),
provideAuth({
apiUrl: 'https://api.myapp.com',
}),
],
};Usage Scenarios
1. Simple JWT (access token only)
No refresh endpoint needed. On a 401 the library closes the session automatically.
provideAuth({
apiUrl: 'https://api.myapp.com',
})Only add jwtInterceptor — refreshTokenInterceptor is not needed:
provideHttpClient(
withInterceptors([jwtInterceptor])
)2. JWT + refresh token
The library detects the 401, calls the refresh endpoint, gets a new access token and retries the original request transparently.
provideAuth({
apiUrl: 'https://api.myapp.com',
endpoints: {
login: '/auth/login',
refresh: '/auth/refresh',
},
})provideHttpClient(
withInterceptors([jwtInterceptor, refreshTokenInterceptor])
)3. Refresh token via HttpOnly Cookie
The refresh token is managed by the server through an HttpOnly cookie. The library does not store the refresh token locally; it simply calls the endpoint and the browser sends the cookie automatically.
provideAuth({
apiUrl: 'https://api.myapp.com',
refreshUsesCookie: true,
endpoints: {
refresh: '/auth/refresh',
},
})provideHttpClient(
withInterceptors([jwtInterceptor, refreshTokenInterceptor])
)Full Configuration — AuthConfig
| Property | Type | Default | Description |
|---|---|---|---|
| apiUrl | string | — | Base API URL (required) |
| endpoints.login | string | /auth/login | Login endpoint |
| endpoints.refresh | string | /auth/refresh | Refresh endpoint |
| storage | 'localStorage' \| 'sessionStorage' | localStorage | Where tokens are stored |
| accessTokenKey | string | access_token | Storage key for the access token |
| refreshTokenKey | string | refresh_token | Storage key for the refresh token |
| tokenMapping.accessToken | string | accessToken | JSON response field containing the access token |
| tokenMapping.refreshToken | string | refreshToken | JSON response field containing the refresh token |
| tokenMapping.user | string | user | JSON response field containing the user |
| refreshUsesCookie | boolean | false | Enables HttpOnly Cookie mode for the refresh token |
Custom configuration example
provideAuth({
apiUrl: 'https://api.myapp.com',
storage: 'sessionStorage',
accessTokenKey: 'jwt',
refreshTokenKey: 'jwt_refresh',
endpoints: {
login: '/v1/session',
refresh: '/v1/session/refresh',
},
tokenMapping: {
accessToken: 'token',
refreshToken: 'refresh',
user: 'profile',
},
})AuthService
Inject AuthService in any component or service to access authentication state and available actions.
import { Component, inject } from '@angular/core';
import { AuthService, LoginCredentials } from 'angular-standard-auth-jwt';
@Component({ ... })
export class LoginComponent {
private auth = inject(AuthService);
// Signals — reactive in templates
user = this.auth.user; // Signal<User | null>
isAuthenticated = this.auth.authenticated; // Signal<boolean>
login(email: string, password: string) {
const credentials: LoginCredentials = { email, password };
this.auth.login(credentials).subscribe({
next: () => {
console.log('Authenticated user:', this.auth.currentUser());
},
error: (err) => console.error(err),
});
}
logout() {
this.auth.logout();
}
}Using Signals in templates
@if (isAuthenticated()) {
<p>Welcome, {{ user()?.email }}</p>
<button (click)="logout()">Sign out</button>
} @else {
<app-login-form />
}AuthService public API
| Method / Property | Return type | Description |
|---|---|---|
| user | Signal<User \| null> | Currently authenticated user |
| authenticated | Signal<boolean> | true if there is an active session |
| login(credentials) | Observable<AuthResponse> | Starts a session |
| logout() | void | Closes the session and clears storage |
| isAuthenticated() | boolean | Instant read of the auth state |
| currentUser() | User \| null | Instant read of the current user |
| accessToken() | string \| null | Stored access token |
| refreshToken() | string \| null | Stored refresh token |
authGuard
Protects routes that require authentication. Redirects to /login if the user is not authenticated.
// app.routes.ts
import { Routes } from '@angular/router';
import { authGuard } from 'angular-standard-auth-jwt';
export const routes: Routes = [
{ path: 'login', component: LoginComponent },
{
path: 'dashboard',
canActivate: [authGuard],
component: DashboardComponent,
},
{
path: 'admin',
canActivate: [authGuard],
loadChildren: () => import('./admin/admin.routes'),
},
];By default the guard redirects to
/login. If your login route is different, you can create your own guard usingAuthService.isAuthenticated()directly.
Interceptors
jwtInterceptor
Automatically adds the Authorization: Bearer <token> header to all HTTP requests when the user is authenticated. No additional configuration required.
refreshTokenInterceptor
Detects 401 Unauthorized responses and attempts to renew the access token before retrying the original request. If the refresh fails, it closes the session automatically.
The order of interceptors matters: jwtInterceptor must come before refreshTokenInterceptor.
withInterceptors([jwtInterceptor, refreshTokenInterceptor])Documentación en Español
Librería Angular moderna para autenticación JWT con soporte para refresh token, Angular Signals, Standalone APIs e interceptores automáticos.
Requisitos
- Angular 20+
- RxJS 7+
- TypeScript 5+
Instalación
npm install angular-standard-auth-jwtConfiguración inicial
Registra la librería en el app.config.ts de tu aplicación usando provideAuth() y los interceptores que necesites:
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { provideRouter } from '@angular/router';
import {
provideAuth,
jwtInterceptor,
refreshTokenInterceptor,
} from 'angular-standard-auth-jwt';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideHttpClient(
withInterceptors([jwtInterceptor, refreshTokenInterceptor])
),
provideAuth({
apiUrl: 'https://api.miapp.com',
}),
],
};Escenarios de uso
1. JWT simple (solo access token)
No se necesita endpoint de refresh. Ante un 401 la librería cierra la sesión automáticamente.
provideAuth({
apiUrl: 'https://api.miapp.com',
})Solo agrega jwtInterceptor — no es necesario el refreshTokenInterceptor:
provideHttpClient(
withInterceptors([jwtInterceptor])
)2. JWT + refresh token
La librería detecta el 401, llama al endpoint de refresh, obtiene un nuevo access token y reintenta la petición original de forma transparente.
provideAuth({
apiUrl: 'https://api.miapp.com',
endpoints: {
login: '/auth/login',
refresh: '/auth/refresh',
},
})provideHttpClient(
withInterceptors([jwtInterceptor, refreshTokenInterceptor])
)3. Refresh token mediante Cookie HttpOnly
El refresh token lo gestiona el servidor a través de una cookie HttpOnly. La librería no almacena el refresh token localmente; simplemente llama al endpoint y el navegador envía la cookie automáticamente.
provideAuth({
apiUrl: 'https://api.miapp.com',
refreshUsesCookie: true,
endpoints: {
refresh: '/auth/refresh',
},
})provideHttpClient(
withInterceptors([jwtInterceptor, refreshTokenInterceptor])
)Configuración completa — AuthConfig
| Propiedad | Tipo | Default | Descripción |
|---|---|---|---|
| apiUrl | string | — | URL base de la API (obligatorio) |
| endpoints.login | string | /auth/login | Endpoint de login |
| endpoints.refresh | string | /auth/refresh | Endpoint de refresh |
| storage | 'localStorage' \| 'sessionStorage' | localStorage | Dónde se almacenan los tokens |
| accessTokenKey | string | access_token | Clave en storage para el access token |
| refreshTokenKey | string | refresh_token | Clave en storage para el refresh token |
| tokenMapping.accessToken | string | accessToken | Campo del response JSON que contiene el access token |
| tokenMapping.refreshToken | string | refreshToken | Campo del response JSON que contiene el refresh token |
| tokenMapping.user | string | user | Campo del response JSON que contiene el usuario |
| refreshUsesCookie | boolean | false | Activa el modo Cookie HttpOnly para el refresh token |
Ejemplo con configuración personalizada
provideAuth({
apiUrl: 'https://api.miapp.com',
storage: 'sessionStorage',
accessTokenKey: 'jwt',
refreshTokenKey: 'jwt_refresh',
endpoints: {
login: '/v1/session',
refresh: '/v1/session/refresh',
},
tokenMapping: {
accessToken: 'token',
refreshToken: 'refresh',
user: 'profile',
},
})AuthService
Inyecta AuthService en cualquier componente o servicio para acceder al estado de autenticación y a las acciones disponibles.
import { Component, inject } from '@angular/core';
import { AuthService, LoginCredentials } from 'angular-standard-auth-jwt';
@Component({ ... })
export class LoginComponent {
private auth = inject(AuthService);
// Signals — reactivos en templates
user = this.auth.user; // Signal<User | null>
isAuthenticated = this.auth.authenticated; // Signal<boolean>
login(email: string, password: string) {
const credentials: LoginCredentials = { email, password };
this.auth.login(credentials).subscribe({
next: () => {
console.log('Usuario autenticado:', this.auth.currentUser());
},
error: (err) => console.error(err),
});
}
logout() {
this.auth.logout();
}
}Uso de Signals en templates
@if (isAuthenticated()) {
<p>Bienvenido, {{ user()?.email }}</p>
<button (click)="logout()">Cerrar sesión</button>
} @else {
<app-login-form />
}API pública de AuthService
| Método / Propiedad | Tipo de retorno | Descripción |
|---|---|---|
| user | Signal<User \| null> | Usuario autenticado actual |
| authenticated | Signal<boolean> | true si hay sesión activa |
| login(credentials) | Observable<AuthResponse> | Inicia sesión |
| logout() | void | Cierra sesión y limpia el storage |
| isAuthenticated() | boolean | Lectura instantánea del estado |
| currentUser() | User \| null | Lectura instantánea del usuario |
| accessToken() | string \| null | Access token almacenado |
| refreshToken() | string \| null | Refresh token almacenado |
authGuard
Protege rutas que requieren autenticación. Redirige a /login si el usuario no está autenticado.
// app.routes.ts
import { Routes } from '@angular/router';
import { authGuard } from 'angular-standard-auth-jwt';
export const routes: Routes = [
{ path: 'login', component: LoginComponent },
{
path: 'dashboard',
canActivate: [authGuard],
component: DashboardComponent,
},
{
path: 'admin',
canActivate: [authGuard],
loadChildren: () => import('./admin/admin.routes'),
},
];Por defecto el guard redirige a
/login. Si tu ruta de login es diferente, puedes crear tu propio guard usandoAuthService.isAuthenticated()directamente.
Interceptores
jwtInterceptor
Agrega automáticamente el header Authorization: Bearer <token> a todas las peticiones HTTP cuando el usuario está autenticado. No requiere configuración adicional.
refreshTokenInterceptor
Detecta respuestas 401 Unauthorized e intenta renovar el access token antes de reintentar la petición original. Si el refresh falla, cierra la sesión automáticamente.
El orden de los interceptores es importante: jwtInterceptor debe ir antes de refreshTokenInterceptor.
withInterceptors([jwtInterceptor, refreshTokenInterceptor])Author / Autor
Christian Camilo Serna Gámez
PRAGMA SA
🇨🇴 Colombia
🟩🟨🟦 100% Chocoano
