Autenticación
La autenticación va a estar basada en firmas. La firma se generará utilizando:
HMAC_SHA256(SHA1(secret_key) + '#' + request_data + '#' + utc_timestamp)
El utc_timestamp
también se incluirá en el encabezado X-Timestamp
o en la URL usando el parámetro _timestamp
. El request_data
contendrá todos los parámetros (URL y POST) y los encabezados relacionados con API. Todos estos datos se escriben en minúsculas, se ordenan y se unen utilizando =
y &
.
En general, la API REST admitirá tres esquemas de autenticación:
Basado en claves de API : la firma incluirá la clave secreta especial asociada con la clave de API en particular. Utilizará el encabezado
X-API-Key
o el parámetro URL_api_key
y el encabezadoX-API-Signature
o el parámetro URL_signature
.Credenciales de usuario : la firma utilizará la contraseña como clave secreta. Utilizará el encabezado
X-API-Signature
o el parámetro URL_signature
y el parámetro URLstaff_name
.Sesión : la firma usará la contraseña del usuario o un código generado especialmente (más detalles a continuación) ... Utilizará el encabezado
X-Session-Signature
o el parámetro_session_signature
URL y el encabezadoX-Session-ID
o el parámetro_session_id
URL.
Tenga en cuenta que la especificación permite utilizar Credenciales de usuario y Sesión al mismo tiempo (es decir, sus encabezados y parámetros no entran en conflicto).
Sesión
Descargo de responsabilidad: Sí, ya sé, las sesiones no son REST completas, ya que son de estado ... Sin embargo, nuestro producto requiere sesiones para cierta funcionalidad, y en aras de la simplicidad queremos mantener una API / protocolo - así que no estoy buscando entrar en un debate RESTful. Prefiero pensar que una sesión es solo un recurso, que debe mantener mientras trabaja con la API.
La sesión será solo un recurso: /api/v1/session
.
Por lo tanto, el procedimiento estándar:
-
Para crear una sesión, una aplicación cliente deberá enviar una solicitud POST utilizando la autenticación credenciales del personal , que se ha descrito anteriormente:
POST /api/v1/session&staff_name=s-andy
. -
El servidor responderá con
201 Created
y entregará el ID de sesión en el cuerpo de la respuesta. -
Posteriormente, la aplicación cliente usará este ID de sesión y la contraseña del personal para acceder a la API.
Tras recibir una solicitud con un ID de sesión particular, el servidor actualizará la última hora de acceso del recurso de sesión apropiado.
Pero nuestros usuarios también tendrán la opción de usar la autenticación de dos factores. En la IU después de iniciar sesión, se solicitará a dichos usuarios que ingresen el código de verificación , que llegará a sus dispositivos móviles. Al diseñar la autenticación, pensé que sería genial tener un 'secreto' especial en lugar de la contraseña de usuario para la sesión. Entonces me di cuenta, ¿por qué no usar este código de verificación ?
Por lo tanto, el flujo para la autenticación de dos factores será:
-
Una aplicación cliente envía una solicitud POST utilizando las credenciales del personal .
-
El servidor inicia la generación y entrega de código de verificación y devuelve
202 Accepted
con el ID de sesión, pero la sesión aún no se ha verificado. -
En 30 segundos, la aplicación cliente envía cualquier solicitud utilizando el identificador de sesión en el encabezado
X-Session-ID
o en el parámetro_session_id
URL y el código de verificación como el secreto para generar la firma. -
Tras recibir dicha solicitud, el servidor actualiza la sesión, la verifica y guarda el código de verificación (también conocida como contraseña de un solo uso) como clave secreta para esta sesión.
-
Luego, la aplicación cliente usará el id de sesión y el código de verificación (como clave secreta) para acceder a la API.
Cuando se agota el tiempo de la sesión y, por lo tanto, se elimina, o cuando el usuario elimina la sesión (es decir, realiza el cierre de sesión), el ID de la sesión y la "contraseña de un solo uso" se vuelven inutilizables.
Quería usar esta comunidad de expertos como una caja de resonancia para esta idea de autenticación de dos factores; ¿Puedes ver alguna trampa que yo no pueda?