jerkjs 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +200 -0
- package/README.md +171 -0
- package/doc/EXTENSION_MANUAL.md +958 -0
- package/doc/FIREWALL_MANUAL.md +419 -0
- package/doc/HOOKS_REFERENCE_IMPROVED.md +599 -0
- package/doc/MANUAL_API_SDK.md +539 -0
- package/doc/MANUAL_MVC.md +397 -0
- package/doc/MARIADB_TOKENS_IMPLEMENTATION.md +113 -0
- package/doc/MIDDLEWARE_MANUAL.md +521 -0
- package/doc/OAUTH2_GOOGLE_MANUAL.md +408 -0
- package/doc/frontend-and-sessions.md +356 -0
- package/examples/advanced/controllers/productController.js +64 -0
- package/examples/advanced/controllers/userController.js +85 -0
- package/examples/advanced/routes.json +51 -0
- package/examples/advanced_example.js +93 -0
- package/examples/basic/controllers/userController.js +85 -0
- package/examples/basic_example.js +72 -0
- package/examples/frontend/README.md +71 -0
- package/examples/frontend/app.js +71 -0
- package/examples/frontend/controllers/apiController.js +39 -0
- package/examples/frontend/controllers/authController.js +220 -0
- package/examples/frontend/controllers/formController.js +47 -0
- package/examples/frontend/controllers/messageController.js +96 -0
- package/examples/frontend/controllers/pageController.js +178 -0
- package/examples/frontend/controllers/staticController.js +167 -0
- package/examples/frontend/routes.json +90 -0
- package/examples/mvc_example/app.js +138 -0
- package/examples/mvc_example/views/home/index.html +26 -0
- package/examples/mvc_example/views/home/simple.html +3 -0
- package/examples/mvc_example/views/layout.html +23 -0
- package/examples/mvc_example/views/test.html +3 -0
- package/examples/mvc_example/views/user/invalid.html +6 -0
- package/examples/mvc_example/views/user/list.html +36 -0
- package/examples/mvc_example/views/user/notfound.html +6 -0
- package/examples/mvc_example/views/user/profile.html +11 -0
- package/examples/mvc_routes_example/app.js +34 -0
- package/examples/mvc_routes_example/controllers/mainController.js +27 -0
- package/examples/mvc_routes_example/controllers/productController.js +47 -0
- package/examples/mvc_routes_example/controllers/userController.js +76 -0
- package/examples/mvc_routes_example/routes.json +30 -0
- package/examples/mvc_routes_example/views/layout.html +31 -0
- package/examples/mvc_routes_example/views/main/index.html +11 -0
- package/examples/mvc_routes_example/views/product/catalog.html +24 -0
- package/examples/mvc_routes_example/views/user/invalid.html +6 -0
- package/examples/mvc_routes_example/views/user/list.html +40 -0
- package/examples/mvc_routes_example/views/user/notfound.html +6 -0
- package/examples/mvc_routes_example/views/user/profile.html +18 -0
- package/examples/public/README.md +92 -0
- package/examples/public/app.js +72 -0
- package/examples/public/controllers/healthController.js +20 -0
- package/examples/public/controllers/mainController.js +22 -0
- package/examples/public/controllers/userController.js +139 -0
- package/examples/public/routes.json +51 -0
- package/examples/v2/README.md +72 -0
- package/examples/v2/app.js +74 -0
- package/examples/v2/app_fixed.js +74 -0
- package/examples/v2/controllers/authController.js +64 -0
- package/examples/v2/controllers/mainController.js +24 -0
- package/examples/v2/controllers/protectedController.js +12 -0
- package/examples/v2/controllers/userController.js +16 -0
- package/examples/v2/package.json +27 -0
- package/examples/v2/routes.json +30 -0
- package/examples/v2/test_api.sh +47 -0
- package/examples/v2/tokens_example.sqlite +0 -0
- package/examples/v2.1_firewall_demo/README.md +113 -0
- package/examples/v2.1_firewall_demo/app.js +182 -0
- package/examples/v2.1_firewall_demo/package.json +27 -0
- package/examples/v2.1_hooks_demo/README.md +85 -0
- package/examples/v2.1_hooks_demo/app.js +101 -0
- package/examples/v2.1_hooks_demo/controllers/hooksController.js +29 -0
- package/examples/v2.1_hooks_demo/controllers/mainController.js +18 -0
- package/examples/v2.1_hooks_demo/package.json +27 -0
- package/examples/v2.1_hooks_demo/routes.json +16 -0
- package/examples/v2.1_openapi_demo/README.md +82 -0
- package/examples/v2.1_openapi_demo/app.js +296 -0
- package/examples/v2.1_openapi_demo/package.json +26 -0
- package/examples/v2_cors/README.md +82 -0
- package/examples/v2_cors/app.js +108 -0
- package/examples/v2_cors/package.json +23 -0
- package/examples/v2_json_auth/README.md +83 -0
- package/examples/v2_json_auth/app.js +72 -0
- package/examples/v2_json_auth/controllers/authController.js +67 -0
- package/examples/v2_json_auth/controllers/mainController.js +16 -0
- package/examples/v2_json_auth/controllers/protectedController.js +12 -0
- package/examples/v2_json_auth/controllers/tokenController.js +28 -0
- package/examples/v2_json_auth/controllers/userController.js +15 -0
- package/examples/v2_json_auth/package.json +26 -0
- package/examples/v2_json_auth/routes.json +37 -0
- package/examples/v2_json_auth/tokens.json +20 -0
- package/examples/v2_mariadb_auth/README.md +94 -0
- package/examples/v2_mariadb_auth/app.js +81 -0
- package/examples/v2_mariadb_auth/controllers/authController.js +95 -0
- package/examples/v2_mariadb_auth/controllers/mainController.js +31 -0
- package/examples/v2_mariadb_auth/controllers/protectedController.js +12 -0
- package/examples/v2_mariadb_auth/controllers/userController.js +17 -0
- package/examples/v2_mariadb_auth/package.json +27 -0
- package/examples/v2_mariadb_auth/routes.json +37 -0
- package/examples/v2_no_auth/README.md +75 -0
- package/examples/v2_no_auth/app.js +72 -0
- package/examples/v2_no_auth/controllers/healthController.js +14 -0
- package/examples/v2_no_auth/controllers/mainController.js +19 -0
- package/examples/v2_no_auth/controllers/productController.js +31 -0
- package/examples/v2_no_auth/controllers/publicController.js +16 -0
- package/examples/v2_no_auth/package.json +22 -0
- package/examples/v2_no_auth/routes.json +37 -0
- package/examples/v2_oauth/README.md +70 -0
- package/examples/v2_oauth/app.js +90 -0
- package/examples/v2_oauth/controllers/mainController.js +45 -0
- package/examples/v2_oauth/controllers/oauthController.js +247 -0
- package/examples/v2_oauth/controllers/protectedController.js +13 -0
- package/examples/v2_oauth/controllers/userController.js +17 -0
- package/examples/v2_oauth/package.json +26 -0
- package/examples/v2_oauth/routes.json +44 -0
- package/examples/v2_openapi/README.md +77 -0
- package/examples/v2_openapi/app.js +222 -0
- package/examples/v2_openapi/controllers/authController.js +52 -0
- package/examples/v2_openapi/controllers/mainController.js +26 -0
- package/examples/v2_openapi/controllers/productController.js +17 -0
- package/examples/v2_openapi/controllers/userController.js +27 -0
- package/examples/v2_openapi/package.json +26 -0
- package/examples/v2_openapi/routes.json +37 -0
- package/generate_token.js +10 -0
- package/index.js +85 -0
- package/jerk.jpg +0 -0
- package/lib/core/handler.js +86 -0
- package/lib/core/hooks.js +224 -0
- package/lib/core/router.js +204 -0
- package/lib/core/securityEnhancedServer.js +752 -0
- package/lib/core/server.js +369 -0
- package/lib/loader/controllerLoader.js +175 -0
- package/lib/loader/routeLoader.js +341 -0
- package/lib/middleware/auditLogger.js +208 -0
- package/lib/middleware/authenticator.js +565 -0
- package/lib/middleware/compressor.js +218 -0
- package/lib/middleware/cors.js +135 -0
- package/lib/middleware/firewall.js +443 -0
- package/lib/middleware/rateLimiter.js +210 -0
- package/lib/middleware/session.js +301 -0
- package/lib/middleware/validator.js +193 -0
- package/lib/mvc/controllerBase.js +207 -0
- package/lib/mvc/viewEngine.js +752 -0
- package/lib/utils/configParser.js +223 -0
- package/lib/utils/logger.js +145 -0
- package/lib/utils/mariadbTokenAdapter.js +226 -0
- package/lib/utils/openapiGenerator.js +140 -0
- package/lib/utils/sqliteTokenAdapter.js +224 -0
- package/lib/utils/tokenManager.js +254 -0
- package/package.json +47 -0
- package/v2examplle/v2_json_auth/README.md +83 -0
- package/v2examplle/v2_json_auth/app.js +72 -0
- package/v2examplle/v2_json_auth/controllers/authController.js +67 -0
- package/v2examplle/v2_json_auth/controllers/mainController.js +16 -0
- package/v2examplle/v2_json_auth/controllers/protectedController.js +12 -0
- package/v2examplle/v2_json_auth/controllers/tokenController.js +28 -0
- package/v2examplle/v2_json_auth/controllers/userController.js +15 -0
- package/v2examplle/v2_json_auth/package.json +26 -0
- package/v2examplle/v2_json_auth/routes.json +37 -0
- package/v2examplle/v2_json_auth/tokens.json +20 -0
- package/v2examplle/v2_mariadb_auth/README.md +94 -0
- package/v2examplle/v2_mariadb_auth/app.js +81 -0
- package/v2examplle/v2_mariadb_auth/controllers/authController.js +95 -0
- package/v2examplle/v2_mariadb_auth/controllers/mainController.js +31 -0
- package/v2examplle/v2_mariadb_auth/controllers/protectedController.js +12 -0
- package/v2examplle/v2_mariadb_auth/controllers/userController.js +17 -0
- package/v2examplle/v2_mariadb_auth/package.json +27 -0
- package/v2examplle/v2_mariadb_auth/routes.json +37 -0
- package/v2examplle/v2_sqlite_auth/README.md +72 -0
- package/v2examplle/v2_sqlite_auth/app.js +74 -0
- package/v2examplle/v2_sqlite_auth/app_fixed.js +74 -0
- package/v2examplle/v2_sqlite_auth/controllers/authController.js +64 -0
- package/v2examplle/v2_sqlite_auth/controllers/mainController.js +24 -0
- package/v2examplle/v2_sqlite_auth/controllers/protectedController.js +12 -0
- package/v2examplle/v2_sqlite_auth/controllers/userController.js +16 -0
- package/v2examplle/v2_sqlite_auth/package.json +27 -0
- package/v2examplle/v2_sqlite_auth/routes.json +30 -0
- package/v2examplle/v2_sqlite_auth/test_api.sh +47 -0
- package/v2examplle/v2_sqlite_auth/tokens_example.sqlite +0 -0
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
# Manual para Implementar OAuth 2.0 con Google usando el Framework API SDK
|
|
2
|
+
|
|
3
|
+
Visita nuestra página web: https://jerk.page.gd/
|
|
4
|
+
Repositorio oficial: https://gitlab.com/bytedogssyndicate1/jerk/
|
|
5
|
+
|
|
6
|
+
## Índice
|
|
7
|
+
1. [Introducción](#introducción)
|
|
8
|
+
2. [Requisitos Previos](#requisitos-previos)
|
|
9
|
+
3. [Configuración en Google Cloud Console](#configuración-en-google-cloud-console)
|
|
10
|
+
4. [Configuración del Framework API SDK](#configuración-del-framework-api-sdk)
|
|
11
|
+
5. [Implementación del Flujo OAuth 2.0](#implementación-del-flujo-oauth-20)
|
|
12
|
+
6. [Manejo de Tokens](#manejo-de-tokens)
|
|
13
|
+
7. [Protección de Endpoints](#protección-de-endpoints)
|
|
14
|
+
8. [Consideraciones de Seguridad](#consideraciones-de-seguridad)
|
|
15
|
+
9. [Depuración y Troubleshooting](#depuración-y-troubleshooting)
|
|
16
|
+
|
|
17
|
+
## Introducción
|
|
18
|
+
|
|
19
|
+
OAuth 2.0 es un protocolo de autorización que permite a aplicaciones de terceros obtener acceso limitado a cuentas de usuario de un servicio web. En este manual, aprenderás cómo implementar OAuth 2.0 con Google usando el Framework API SDK.
|
|
20
|
+
|
|
21
|
+
## Requisitos Previos
|
|
22
|
+
|
|
23
|
+
- Cuenta de Google
|
|
24
|
+
- Acceso a Google Cloud Console
|
|
25
|
+
- Node.js instalado
|
|
26
|
+
- Framework API SDK instalado
|
|
27
|
+
- Conocimientos básicos de JavaScript y APIs REST
|
|
28
|
+
|
|
29
|
+
## Configuración en Google Cloud Console
|
|
30
|
+
|
|
31
|
+
### Paso 1: Crear un proyecto en Google Cloud Console
|
|
32
|
+
|
|
33
|
+
1. Accede a [Google Cloud Console](https://console.cloud.google.com/)
|
|
34
|
+
2. Haz clic en "Seleccionar un proyecto" o "Nuevo proyecto"
|
|
35
|
+
3. Ingresa un nombre para tu proyecto
|
|
36
|
+
4. Haz clic en "Crear"
|
|
37
|
+
|
|
38
|
+
### Paso 2: Habilitar Google+ API (o las APIs que necesites)
|
|
39
|
+
|
|
40
|
+
1. En el panel lateral izquierdo, haz clic en "APIs y servicios" > "Biblioteca"
|
|
41
|
+
2. Busca "Google+ API" o las APIs que planeas usar (como People API)
|
|
42
|
+
3. Haz clic en "Habilitar"
|
|
43
|
+
|
|
44
|
+
### Paso 3: Crear credenciales OAuth 2.0
|
|
45
|
+
|
|
46
|
+
1. En el panel lateral izquierdo, haz clic en "APIs y servicios" > "Credenciales"
|
|
47
|
+
2. Haz clic en "Crear credenciales" > "ID de cliente OAuth 2.0"
|
|
48
|
+
3. Si aún no has configurado el consentimiento OAuth, haz clic en "Configurar pantalla de consentimiento OAuth"
|
|
49
|
+
4. Completa la información de la pantalla de consentimiento:
|
|
50
|
+
- Tipo de usuario: Público o Interno (según tu necesidad)
|
|
51
|
+
- Ingresa un nombre de aplicación
|
|
52
|
+
- Agrega direcciones de correo electrónico de desarrolladores
|
|
53
|
+
- Ingresa un dominio de aplicación (si aplica)
|
|
54
|
+
5. Guarda la configuración de consentimiento
|
|
55
|
+
|
|
56
|
+
### Paso 4: Configurar las credenciales
|
|
57
|
+
|
|
58
|
+
1. De vuelta en la página de credenciales, haz clic en "Crear credenciales" > "ID de cliente OAuth 2.0"
|
|
59
|
+
2. Selecciona "Aplicación web" como tipo de aplicación
|
|
60
|
+
3. Ingresa un nombre para las credenciales
|
|
61
|
+
4. En "URI de redirección autorizados", agrega las siguientes URLs:
|
|
62
|
+
- `http://localhost:8093/auth/callback` (ajusta el puerto según tu configuración)
|
|
63
|
+
- `http://localhost:3000/auth/callback` (si usas otro puerto)
|
|
64
|
+
- Cualquier otra URL de callback que vayas a usar
|
|
65
|
+
5. Haz clic en "Crear"
|
|
66
|
+
6. Guarda el "ID de cliente" y el "Secreto de cliente" que se mostrarán
|
|
67
|
+
|
|
68
|
+
## Configuración del Framework API SDK
|
|
69
|
+
|
|
70
|
+
### Paso 1: Instalar el Framework API SDK
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm install jerk
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Paso 2: Configurar variables de entorno
|
|
77
|
+
|
|
78
|
+
Crea un archivo `.env` en la raíz de tu proyecto:
|
|
79
|
+
|
|
80
|
+
```env
|
|
81
|
+
OAUTH_CLIENT_ID=tu_client_id_aqui
|
|
82
|
+
OAUTH_CLIENT_SECRET=tu_client_secret_aqui
|
|
83
|
+
OAUTH_CALLBACK_URL=http://localhost:8093/auth/callback
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Paso 3: Importar los componentes necesarios
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
const {
|
|
90
|
+
APIServer,
|
|
91
|
+
Authenticator,
|
|
92
|
+
RouteLoader,
|
|
93
|
+
Logger,
|
|
94
|
+
TokenManager
|
|
95
|
+
} = require('jerk');
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Implementación del Flujo OAuth 2.0
|
|
99
|
+
|
|
100
|
+
### Paso 1: Configurar el servidor y autenticador
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
const server = new APIServer({
|
|
104
|
+
port: 8093,
|
|
105
|
+
host: 'localhost'
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const authenticator = new Authenticator({ logger });
|
|
109
|
+
|
|
110
|
+
// Registrar la estrategia OAuth2
|
|
111
|
+
authenticator.use('google-oauth', authenticator.oauth2Strategy({
|
|
112
|
+
clientId: process.env.OAUTH_CLIENT_ID,
|
|
113
|
+
clientSecret: process.env.OAUTH_CLIENT_SECRET,
|
|
114
|
+
callbackURL: process.env.OAUTH_CALLBACK_URL,
|
|
115
|
+
authorizationURL: 'https://accounts.google.com/o/oauth2/v2/auth',
|
|
116
|
+
tokenURL: 'https://oauth2.googleapis.com/token'
|
|
117
|
+
}));
|
|
118
|
+
|
|
119
|
+
// Agregar autenticador al servidor
|
|
120
|
+
server.authenticator = authenticator;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Paso 2: Crear el endpoint para iniciar OAuth
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
// Ruta para iniciar el flujo OAuth
|
|
127
|
+
router.get('/auth/google', (req, res) => {
|
|
128
|
+
// El framework maneja la redirección a Google
|
|
129
|
+
const authMiddleware = authenticator.authenticate('google-oauth');
|
|
130
|
+
authMiddleware(req, res, () => {});
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Paso 3: Crear el endpoint de callback
|
|
135
|
+
|
|
136
|
+
```javascript
|
|
137
|
+
// Ruta para manejar el callback de OAuth
|
|
138
|
+
router.get('/auth/callback', async (req, res) => {
|
|
139
|
+
try {
|
|
140
|
+
// El framework maneja la autenticación y el intercambio de código por token
|
|
141
|
+
const authMiddleware = authenticator.authenticate('google-oauth', {
|
|
142
|
+
failureRedirect: '/login'
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Ejecutar middleware de autenticación
|
|
146
|
+
authMiddleware(req, res, async () => {
|
|
147
|
+
// Si llegamos aquí, la autenticación fue exitosa
|
|
148
|
+
if (req.user) {
|
|
149
|
+
// Generar token JWT para el usuario autenticado
|
|
150
|
+
const token = jwt.sign({
|
|
151
|
+
userId: req.user.id,
|
|
152
|
+
email: req.user.email,
|
|
153
|
+
name: req.user.name
|
|
154
|
+
}, process.env.JWT_SECRET);
|
|
155
|
+
|
|
156
|
+
// Redirigir con token o mostrar página de éxito
|
|
157
|
+
res.writeHead(302, { 'Location': `/dashboard?token=${token}` });
|
|
158
|
+
res.end();
|
|
159
|
+
} else {
|
|
160
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
161
|
+
res.end(JSON.stringify({ error: 'Autenticación fallida' }));
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.error('Error en callback OAuth:', error);
|
|
166
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
167
|
+
res.end(JSON.stringify({ error: 'Error interno del servidor' }));
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Manejo de Tokens
|
|
173
|
+
|
|
174
|
+
### Paso 1: Configurar TokenManager
|
|
175
|
+
|
|
176
|
+
```javascript
|
|
177
|
+
const tokenManager = new TokenManager({
|
|
178
|
+
storage: 'memory' // Opciones: 'memory', 'json', 'database'
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Paso 2: Generar tokens JWT
|
|
183
|
+
|
|
184
|
+
```javascript
|
|
185
|
+
// Generar token JWT después de autenticación exitosa
|
|
186
|
+
const generateToken = (userData) => {
|
|
187
|
+
return jwt.sign(
|
|
188
|
+
{
|
|
189
|
+
userId: userData.id,
|
|
190
|
+
email: userData.email,
|
|
191
|
+
name: userData.name,
|
|
192
|
+
provider: 'google'
|
|
193
|
+
},
|
|
194
|
+
process.env.JWT_SECRET,
|
|
195
|
+
{ expiresIn: '1h' }
|
|
196
|
+
);
|
|
197
|
+
};
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Paso 3: Validar tokens
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
// Middleware para validar tokens JWT
|
|
204
|
+
const validateToken = (req, res, next) => {
|
|
205
|
+
const authHeader = req.headers.authorization;
|
|
206
|
+
const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
|
|
207
|
+
|
|
208
|
+
if (!token) {
|
|
209
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
210
|
+
res.end(JSON.stringify({ error: 'Token no proporcionado' }));
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
|
|
215
|
+
if (err) {
|
|
216
|
+
res.writeHead(403, { 'Content-Type': 'application/json' });
|
|
217
|
+
res.end(JSON.stringify({ error: 'Token inválido' }));
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
req.user = decoded;
|
|
222
|
+
next();
|
|
223
|
+
});
|
|
224
|
+
};
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Protección de Endpoints
|
|
228
|
+
|
|
229
|
+
### Paso 1: Proteger rutas individuales
|
|
230
|
+
|
|
231
|
+
```javascript
|
|
232
|
+
// Proteger una ruta específica
|
|
233
|
+
router.get('/profile', validateToken, (req, res) => {
|
|
234
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
235
|
+
res.end(JSON.stringify({
|
|
236
|
+
user: req.user,
|
|
237
|
+
message: 'Perfil de usuario protegido'
|
|
238
|
+
}));
|
|
239
|
+
});
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Paso 2: Proteger rutas usando el framework
|
|
243
|
+
|
|
244
|
+
```javascript
|
|
245
|
+
// Usar la estrategia JWT del framework
|
|
246
|
+
authenticator.use('jwt-auth', (req, options = {}) => {
|
|
247
|
+
const authHeader = req.headers.authorization;
|
|
248
|
+
const token = authHeader && authHeader.split(' ')[1];
|
|
249
|
+
|
|
250
|
+
if (!token) return false;
|
|
251
|
+
|
|
252
|
+
try {
|
|
253
|
+
const decoded = jwt.verify(token, process.env.JWT_SECRET);
|
|
254
|
+
req.user = decoded;
|
|
255
|
+
return true;
|
|
256
|
+
} catch (error) {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
// Proteger ruta con autenticación JWT
|
|
262
|
+
router.get('/protected', authenticator.authenticate('jwt-auth'), (req, res) => {
|
|
263
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
264
|
+
res.end(JSON.stringify({ message: 'Contenido protegido', user: req.user }));
|
|
265
|
+
});
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Consideraciones de Seguridad
|
|
269
|
+
|
|
270
|
+
### 1. Almacenamiento de credenciales
|
|
271
|
+
|
|
272
|
+
- Nunca almacenes credenciales en el código fuente
|
|
273
|
+
- Usa variables de entorno o servicios de gestión de secretos
|
|
274
|
+
- Rotar periódicamente los secrets
|
|
275
|
+
|
|
276
|
+
### 2. Validación de tokens
|
|
277
|
+
|
|
278
|
+
- Siempre valida tokens antes de conceder acceso
|
|
279
|
+
- Implementa expiración de tokens
|
|
280
|
+
- Considera usar refresh tokens para largas sesiones
|
|
281
|
+
|
|
282
|
+
### 3. Configuración de Google
|
|
283
|
+
|
|
284
|
+
- Limita las URLs de redirección a solo las que necesitas
|
|
285
|
+
- Usa HTTPS en producción
|
|
286
|
+
- Monitorea el uso de tus credenciales
|
|
287
|
+
|
|
288
|
+
### 4. Manejo de errores
|
|
289
|
+
|
|
290
|
+
- No reveles información sensible en mensajes de error
|
|
291
|
+
- Implementa logging adecuado para auditoría
|
|
292
|
+
- Maneja correctamente los casos de fallo de autenticación
|
|
293
|
+
|
|
294
|
+
## Depuración y Troubleshooting
|
|
295
|
+
|
|
296
|
+
### Problemas comunes y soluciones
|
|
297
|
+
|
|
298
|
+
#### 1. Error: "redirect_uri_mismatch"
|
|
299
|
+
- **Causa**: La URL de redirección no coincide con las registradas en Google Cloud Console
|
|
300
|
+
- **Solución**: Verifica que la URL en tu código coincida exactamente con las registradas
|
|
301
|
+
|
|
302
|
+
#### 2. Error: "invalid_client"
|
|
303
|
+
- **Causa**: Client ID o Client Secret incorrectos
|
|
304
|
+
- **Solución**: Verifica que las credenciales sean correctas y no estén truncadas
|
|
305
|
+
|
|
306
|
+
#### 3. Token expirado
|
|
307
|
+
- **Causa**: El access token ha expirado
|
|
308
|
+
- **Solución**: Implementa refresh tokens o solicita nuevo acceso
|
|
309
|
+
|
|
310
|
+
### Herramientas de depuración
|
|
311
|
+
|
|
312
|
+
```javascript
|
|
313
|
+
// Habilitar logging detallado
|
|
314
|
+
const logger = new Logger({ level: 'debug' });
|
|
315
|
+
|
|
316
|
+
// Verificar estado de autenticación
|
|
317
|
+
console.log('Usuario autenticado:', req.user);
|
|
318
|
+
console.log('Headers:', req.headers);
|
|
319
|
+
console.log('Query params:', req.query);
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Pruebas
|
|
323
|
+
|
|
324
|
+
```javascript
|
|
325
|
+
// Prueba de endpoint protegido
|
|
326
|
+
const testProtectedEndpoint = async (token) => {
|
|
327
|
+
const response = await fetch('http://localhost:8093/protected', {
|
|
328
|
+
headers: {
|
|
329
|
+
'Authorization': `Bearer ${token}`
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
const data = await response.json();
|
|
334
|
+
console.log('Respuesta del endpoint protegido:', data);
|
|
335
|
+
};
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## Ejemplo Completo
|
|
339
|
+
|
|
340
|
+
Aquí tienes un ejemplo completo de implementación:
|
|
341
|
+
|
|
342
|
+
```javascript
|
|
343
|
+
const {
|
|
344
|
+
APIServer,
|
|
345
|
+
Authenticator,
|
|
346
|
+
Router,
|
|
347
|
+
Logger
|
|
348
|
+
} = require('jerk');
|
|
349
|
+
|
|
350
|
+
const jwt = require('jsonwebtoken');
|
|
351
|
+
|
|
352
|
+
async function startServer() {
|
|
353
|
+
const server = new APIServer({
|
|
354
|
+
port: 8093,
|
|
355
|
+
host: 'localhost'
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
const logger = new Logger({ level: 'info' });
|
|
359
|
+
const router = new Router();
|
|
360
|
+
const authenticator = new Authenticator({ logger });
|
|
361
|
+
|
|
362
|
+
// Configurar estrategia OAuth2
|
|
363
|
+
authenticator.use('google-oauth', authenticator.oauth2Strategy({
|
|
364
|
+
clientId: process.env.OAUTH_CLIENT_ID,
|
|
365
|
+
clientSecret: process.env.OAUTH_CLIENT_SECRET,
|
|
366
|
+
callbackURL: process.env.OAUTH_CALLBACK_URL,
|
|
367
|
+
}));
|
|
368
|
+
|
|
369
|
+
// Agregar autenticador al servidor
|
|
370
|
+
server.authenticator = authenticator;
|
|
371
|
+
|
|
372
|
+
// Ruta para iniciar OAuth
|
|
373
|
+
router.get('/auth/google', (req, res) => {
|
|
374
|
+
authenticator.authenticate('google-oauth')(req, res, () => {});
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
// Ruta de callback
|
|
378
|
+
router.get('/auth/callback', (req, res) => {
|
|
379
|
+
authenticator.authenticate('google-oauth', {
|
|
380
|
+
successRedirect: '/dashboard',
|
|
381
|
+
failureRedirect: '/login'
|
|
382
|
+
})(req, res, () => {});
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
// Ruta protegida
|
|
386
|
+
router.get('/dashboard', (req, res) => {
|
|
387
|
+
if (req.user) {
|
|
388
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
389
|
+
res.end(JSON.stringify({ message: 'Bienvenido al dashboard', user: req.user }));
|
|
390
|
+
} else {
|
|
391
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
392
|
+
res.end(JSON.stringify({ error: 'No autorizado' }));
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
// Agregar rutas al servidor
|
|
397
|
+
for (const route of router.getRoutes()) {
|
|
398
|
+
server.addRoute(route.method, route.path, route.handler);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
server.start();
|
|
402
|
+
logger.info('Servidor iniciado en http://localhost:8093');
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
startServer();
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
Este manual proporciona una guía completa para implementar OAuth 2.0 con Google usando el Framework API SDK, desde la configuración inicial hasta la implementación completa y consideraciones de seguridad.
|