Cliente OAuth para TypeScript: implementación de autorización en un sitio educativo
\n\nEn el desarrollo web moderno, OAuth (Open Authorization) se ha convertido en el estándar de facto para la autenticación de usuarios a través de servicios de terceros. Para el sitio educativo pythonlib.ru hemos preparado una descripción de un cliente OAuth universal en TypeScript, que permite implementar el inicio de sesión a través de GitHub, Google y otros proveedores populares.
\n\n¿Qué es un cliente OAuth?
\nUn cliente OAuth es un componente de software que gestiona el proceso de obtención de permisos del usuario para acceder a sus datos en un servicio de terceros. En el contexto de TypeScript, dicho cliente generalmente implementa el protocolo OAuth 2.0 e incluye:
\n- \n
- Inicialización del proceso de autorización \n
- Manejo de solicitudes de callback \n
- Intercambio de authorization code por access token \n
- Actualización de tokens (refresh token) \n
- Trabajo con el estado de la sesión \n
Arquitectura del cliente OAuth en TypeScript
\nNuestro cliente está construido sobre los principios de modularidad y seguridad de tipos. Componentes principales:
\n\n1. Configuración del proveedor
\ninterface OAuthProviderConfig {\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n authorizationEndpoint: string;\n tokenEndpoint: string;\n scopes: string[];\n}\n\nconst githubConfig: OAuthProviderConfig = {\n clientId: process.env.GITHUB_CLIENT_ID!,\n clientSecret: process.env.GITHUB_CLIENT_SECRET!,\n redirectUri: 'https://pythonlib.ru/auth/callback/github',\n authorizationEndpoint: 'https://github.com/login/oauth/authorize',\n tokenEndpoint: 'https://github.com/login/oauth/access_token',\n scopes: ['read:user', 'user:email']\n};\n\n2. Generación de URL para autorización
\nfunction generateAuthUrl(config: OAuthProviderConfig, state: string): string {\n const params = new URLSearchParams({\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n scope: config.scopes.join(' '),\n state: state,\n response_type: 'code'\n });\n \n return `${config.authorizationEndpoint}?${params.toString()}`;\n}\n\n3. Intercambio de código por token
\nasync function exchangeCodeForToken(\n config: OAuthProviderConfig,\n code: string\n): Promise<OAuthTokenResponse> {\n const response = await fetch(config.tokenEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n },\n body: JSON.stringify({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n code: code,\n redirect_uri: config.redirectUri\n })\n });\n\n if (!response.ok) {\n throw new Error(`Token exchange failed: ${response.statusText}`);\n }\n\n return response.json();\n}\n\nTrabajo con tokens
\nDespués de obtener los tokens, es necesario garantizar su almacenamiento seguro y actualización. Se recomienda usar httpOnly cookies o almacenamiento de sesiones en el servidor.
\n\nActualización del access token
\nasync function refreshAccessToken(\n config: OAuthProviderConfig,\n refreshToken: string\n): Promise<OAuthTokenResponse> {\n const response = await fetch(config.tokenEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n refresh_token: refreshToken,\n grant_type: 'refresh_token'\n })\n });\n\n return response.json();\n}\n\nEjemplo completo de implementación para GitHub OAuth
\nimport { randomBytes } from 'crypto';\n\nclass GitHubOAuthClient {\n private config: OAuthProviderConfig;\n private stateStore: Map<string, string> = new Map();\n\n constructor() {\n this.config = {\n clientId: process.env.GITHUB_CLIENT_ID!,\n clientSecret: process.env.GITHUB_CLIENT_SECRET!,\n redirec También en la biblioteca
RxJava para Java: guía completa con ejemplos prácticos
Frameworks CLI para TypeScript: revisión completa y ejemplos de uso
Bull para JavaScript (Node.js): guía completa con ejemplos
Trabajo con S3 y almacenamiento en la nube en Go: biblioteca minio-go
Flurl para C# (.NET): guía completa con ejemplos prácticos