Cliente OAuth para TypeScript: integración de autorización en aplicaciones web

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Cliente OAuth para TypeScript: guía completa de implementación de autorización

\n

En el desarrollo web moderno, la autenticación segura de usuarios es una de las tareas clave. OAuth 2.0 es un protocolo de autorización abierto que permite a las aplicaciones obtener acceso limitado a los recursos del usuario sin transferir nombre de usuario y contraseña. En este artículo, analizaremos cómo crear un cliente OAuth en TypeScript que se pueda usar en cualquier aplicación web. La biblioteca es adecuada para la integración con Google, GitHub, Facebook y otros proveedores.

\n\n

¿Qué es un cliente OAuth en TypeScript?

\n

Un cliente OAuth es un conjunto de funciones y clases que implementan el flujo de autorización (Authorization Code Flow) del lado del cliente o del servidor. En TypeScript, dicho cliente proporciona una tipificación estricta, lo que reduce la cantidad de errores y simplifica el mantenimiento del código. Las tareas principales del cliente son:

\n
    \n
  • Generación de URL para redirigir al usuario a la página del proveedor.
  • \n
  • Intercambio del código temporal por un access token y refresh token.
  • \n
  • Almacenamiento y actualización de tokens.
  • \n
  • Validación de parámetros de solicitud (state, nonce).
  • \n
\n\n

Arquitectura de la biblioteca

\n

La biblioteca consta de varios módulos:

\n
    \n
  • OAuthClient — la clase principal que gestiona todas las etapas.
  • \n
  • TokenStore — interfaz para almacenar tokens (se puede implementar en memoria, localStorage o base de datos).
  • \n
  • ProviderConfig — configuración para un proveedor específico (clientId, redirectUri, endpoints).
  • \n
  • AuthError — clase para manejar errores de autorización.
  • \n
\n\n

Ejemplo de implementación en TypeScript

\n

A continuación se muestra un ejemplo básico de un cliente OAuth para TypeScript. Primero, definimos los tipos e interfaces:

\n
// types.ts\nexport interface TokenResponse {\n    access_token: string;\n    token_type: string;\n    expires_in: number;\n    refresh_token?: string;\n    scope?: string;\n}\n\nexport interface ProviderConfig {\n    authorizationEndpoint: string;\n    tokenEndpoint: string;\n    clientId: string;\n    redirectUri: string;\n    scope: string;\n}\n\nexport interface TokenStore {\n    getToken(): Promise<string | null>;\n    setToken(token: TokenResponse): Promise<void>;\n    clearToken(): Promise<void>;\n}
\n\n

Ahora creamos la clase principal OAuthClient:

\n
// OAuthClient.ts\nimport { TokenResponse, ProviderConfig, TokenStore } from './types';\nimport { AuthError } from './AuthError';\n\nexport class OAuthClient {\n    private config: ProviderConfig;\n    private store: TokenStore;\n\n    constructor(config: ProviderConfig, store: TokenStore) {\n        this.config = config;\n        this.store = store;\n    }\n\n    // Generación de URL para autorización\n    getAuthorizationUrl(state: string): string {\n        const params = new URLSearchParams({\n            client_id: this.config.clientId,\n            redirect_uri: this.config.redirectUri,\n            response_type: 'code',\n            scope: this.config.scope,\n            state: state,\n        });\n        return `${this.config.authorizationEndpoint}?${params.toString()}`;\n    }\n\n    // Intercambio de código por token\n    async exchangeCodeForToken(code: string, state: string, expectedState: string): Promise<TokenResponse> {\n        if (state !== expectedState) {\n            throw new AuthError('State mismatch. Possible CSRF attack.');\n        }\n\n        const body = new URLSearchParams({\n            grant_type: 'authorization_code',\n            code: code,\n            redirect_uri: this.config.redirectUri,\n            client_id: this.config.clientId,\n        });\n\n        const response = await fetch(this.config.tokenEndpoint, {\n            method: 'POST',\n            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n            body: body,\n        });\n\n        if (!response.ok)                    

Recommendations