En el desarrollo de aplicaciones híbridas, la gestión segura de tokens de autenticación es fundamental para proteger los recursos y evitar vulnerabilidades. Este enfoque se centra en cómo manejar tokens sin exponerlos en el entorno JavaScript, utilizando una arquitectura que delega solicitudes autenticadas a la capa nativa.
Clasificación de endpoints según nivel de riesgo
Una estrategia efectiva implica categorizar los endpoints en tres niveles, definiendo claramente qué operaciones puede realizar el front-end H5 y cuáles deben gestionarse de forma nativa.
1. Endpoints públicos sin autenticación
Para recursos sin información sesnible, el front-end puede realizar solicitudes directas. Ejemplos incluyen configuraciones globales, listados de contenido público o datos de productos. Aquí, el H5 utiliza métodos estándar de HTTP sin incluir credenciales.
// Ejemplo de solicitud pública desde H5
fetch('/api/public/settings')
.then(res => res.json())
.then(data => console.log('Configuración:', data));
2. Endpoints autenticados de riesgo moderado
Operaciones que requieren inicio de sesión pero no invoulcran datos altamente sensibles. El H5 no debe acceder al token; en su lugar, se invoca un puente nativo que inyecta el token en la capa nativa.
// Invocación a través de JSBridge para solicitudes autenticadas
window.nativeGateway.send({
path: '/user/profile',
method: 'GET',
params: {},
onSuccess: (response) => console.log('Perfil:', response),
onError: (err) => console.error('Error:', err)
});
3. Endpoints de alto riesgo
Transacciones críticas como pagos, actualización de tokens o manipulación de activos. Estas solicitudes deben ser exclusivamente manejadas por la capa nativa, con medidas de seguridad adicionales como firmas digitales o anclaje de TLS.
Problemas de exponer tokens en H5
Almacenar tokens en variables globales de JavaScript, localStorage o incluso en cookies sin bandera HttpOnly los hace accesibles a scripts maliciosos a través de ataques XSS. Esto compromete la seguridad integral de la aplicación.
Implementación en la capa nativa
La capa nativa actúa como un intermediario seguro, gestionando la inyección de tokens y la ejecución de solicitudes con parámetros de seguridad adicionales.
// Ejemplo en Kotlin para el manejador de solicitudes nativas
@JavascriptInterface
fun handleBridgeRequest(jsonRequest: String) {
val requestData = deserializeJson(jsonRequest)
val authToken = secureStorage.getToken()
val deviceHash = getDeviceIdentifier()
val request = HttpRequest.Builder()
.url(baseUrl + requestData.endpoint)
.method(requestData.httpMethod)
.header("Authorization", "Bearer $authToken")
.header("X-Device-Fingerprint", deviceHash)
.body(requestData.payload)
.build()
asyncHttpClient.newCall(request).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
val result = response.body?.string()
webViewBridge.emitSuccess(requestData.callbackId, result)
}
override fun onFailure(call: Call, e: IOException) {
webViewBridge.emitError(requestData.callbackId, e.message)
}
})
}
Ventajas de esta arquitectura
- Seguridad reforzada: Los tokens nunca están expuestos en el entorno JavaScript, reduciendo superficies de ataque.
- Simplificación del desarrollo front-end: Los desarrolladores H5 se enfocan en la interfaz sin gestionar lógica de autenticación.
- Control centralizado: La capa nativa puede aplicar políticas de seguridad como validación de certificados, limitación de velocidad o cifrado adicional.
- Mantenibilidad clara: La separación de responsabilidades entre la capa de presentación (H5) y la capa de seguridad (nativa) facilita actualizaciones y auditorías.