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 signmage seguido 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 payload y 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.

En esta página