Errores 401
Cómo diagnosticar una petición que devuelve 401, paso por paso.
Un 401 llega con el cuerpo vacío y cubre tres situaciones distintas: el Web ID no se reconoce, la
llave no está activa, o la firma no coincide.
1. Descarta lo simple
Antes de revisar la firma, confirma que el encabezado llegó completo y bien formado:
- Empieza con
signmageseguido de un espacio. - Entre el Web ID y la firma va un
:, sin espacios alrededor. - La firma va en Base64, no en hexadecimal.
Authorization: signmage TU_WEB_ID:PWJhc2U2NCBkZWwgSE1BQz4=Si el Web ID o la llave no son los que te asignaron, o la llave ya no está activa, escribe a [email protected]
2. En GET, la URI se firma tal cual
La cadena firmada es la ruta con su query string, exactamente como sale en la petición. Eso significa que el orden de los parámetros y su codificación forman parte de la firma.
// Construye la ruta una vez y usa esa misma cadena para firmar y para pedir.
const path = '/api/document?from=1640995200000&to=1641945600000';
const auth = authorization(path);
await fetch(`https://app.firmame.com${path}`, { headers: { Authorization: auth } });Lo que suele descuadrar:
- Armar la URL con un objeto y dejar que la librería reordene los parámetros.
- Firmar la ruta sin query string y luego enviarla con parámetros.
- Codificar un valor al firmar y no al enviar, o al revés.
3. En POST con JSON, serializa una sola vez
La comparación se hace contra tu JSON compacto: sin espacios ni saltos de línea. Serializa una vez, firma esa cadena y manda exactamente esos bytes.
const body = JSON.stringify(payload); // una sola serialización
await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: authorization(body) },
body, // los mismos bytes que se firmaron
});Lo que suele descuadrar:
- Firmar
payloady dejar que el cliente HTTP serialice por su cuenta al enviar. Dos serializaciones distintas producen dos cadenas distintas. - Usar un formateador con indentación al firmar.
- Un cliente que agrega un salto de línea final al cuerpo.
Nota sobre los números: 1.0 y 1 son el mismo valor en JSON pero no la misma cadena. Si tu payload
lleva decimales, revisa que sobrevivan igual a la serialización que firmas y a la que envías.
4. En POST multipart, se firma el hash del archivo
La cadena firmada es el SHA-256 del archivo en Base64, y ese mismo valor va en el encabezado
Content-SHA256. El archivo viaja en el campo file.
const hash = createHash('sha256').update(fileBytes).digest('base64');
const headers = {
Authorization: authorization(hash),
'Content-SHA256': hash,
};5. Si aún falla, compara la cadena
Cuando los cuatro puntos anteriores están bien y el 401 sigue, imprime la cadena que estás firmando y
revísala carácter por carácter contra lo que realmente sale por la red.
Un atajo
Los SDKs construyen la firma por ti en los cuatro casos. Si tu lenguaje está en la lista, es la vía más directa.