Solución:
Dado que AWS Cognito no admite actualmente la autenticación sin contraseña, debe implementar una solución alternativa con una contraseña aleatoria almacenada externamente. Puede implementar el flujo de autenticación de la siguiente manera.
- Después del registro del usuario (también solicite el número de teléfono móvil y hágalo obligatorio), almacene el número de teléfono móvil, el nombre de usuario y la contraseña también en Dynamodb cifrado con AWS KMS (para mayor seguridad).
- Puede usar MFA con el número de teléfono móvil para el desafío de autenticación, de modo que después de que el usuario ingrese el número de teléfono móvil y presione iniciar sesión (en el frontend), en el backend pueda hacer coincidir automáticamente la contraseña del nombre de usuario (Passthrough) y activar el MFA para enviar un código para el teléfono móvil del usuario. y verificarlo con el SDK de AWS Cognito (sin implementar mensajes móviles personalizados ni desafíos).
- Si planea implementar el flujo manualmente (sin MFA) para enviar el SMS y la validación, puede usar AWS SNS para este propósito.
Consulte el siguiente ejemplo de código para comprender la información de MFA y consulte este enlace para obtener más detalles.
var userData = {
Username : 'username',
Pool : userPool
};
cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);
var authenticationData = {
Username : 'username',
Password : 'password',
};
var authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
alert('authentication successful!')
},
onFailure: function(err) {
alert(err);
},
mfaRequired: function(codeDeliveryDetails) {
var verificationCode = prompt('Please input verification code' ,'');
cognitoUser.sendMFACode(verificationCode, this);
}
});
Nota: Aquí, el MFA con número de teléfono móvil no se utiliza para fines de MFA, sino como una solución alternativa para cumplir con sus requisitos.
Este es un giro ligeramente diferente a lo que solicita el OP, ya que usa un solo secreto, pero creo que puede ayudar a otros que aterrizan en esta pregunta.
Pude hacer esto creando lambdas personalizadas para los desencadenantes de Cognito: Definir desafío de autenticación, Crear desafío de autenticación y Verificar desafío de autenticación.
Mi requisito era que quería que mi backend usara un secret
para luego obtener acceso y actualizar tokens para cualquier usuario de Cognito.
Definir Lambda de desafío de autenticación
exports.handler = async event => {
if (
event.request.session &&
event.request.session.length >= 3 &&
event.request.session.slice(-1)[0].challengeResult === false
) {
// The user provided a wrong answer 3 times; fail auth
event.response.issueTokens = false;
event.response.failAuthentication = true;
} else if (
event.request.session &&
event.request.session.length &&
event.request.session.slice(-1)[0].challengeResult === true
) {
// The user provided the right answer; succeed auth
event.response.issueTokens = true;
event.response.failAuthentication = false;
} else {
// The user did not provide a correct answer yet; present challenge
event.response.issueTokens = false;
event.response.failAuthentication = false;
event.response.challengeName="CUSTOM_CHALLENGE";
}
return event;
};
Crear Lambda de desafío de autenticación
exports.handler = async event => {
if (event.request.challengeName == 'CUSTOM_CHALLENGE') {
// The value set for publicChallengeParameters is arbitrary for our
// purposes, but something must be set
event.response.publicChallengeParameters = { foo: 'bar' };
}
return event;
};
Verificar Lambda de desafío de autenticación
exports.handler = async event => {
if (event.request.challengeName == 'CUSTOM_CHALLENGE') {
// The value set for publicChallengeParameters is arbitrary for our
// purposes, but something must be set
event.response.publicChallengeParameters = { foo: 'bar' };
}
return event;
};
Luego pude usar algo de JS, usando amazon-cognito-identity-js, para proporcionar el secreto y obtener los tokens:
var authenticationData = {
Username : 'username'
};
var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData);
var poolData = {
UserPoolId : '...', // Your user pool id here
ClientId : '...' // Your client id here
};
var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
var userData = {
Username : 'username',
Pool : userPool
};
var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
cognitoUser.setAuthenticationFlowType('CUSTOM_AUTH');
cognitoUser.initiateAuth(authenticationDetails, {
onSuccess: function(result) {
// User authentication was successful
},
onFailure: function(err) {
// User authentication was not successful
},
customChallenge: function(challengeParameters) {
// User authentication depends on challenge response
var challengeResponses="secret"
cognitoUser.sendCustomChallengeAnswer(challengeResponses, this);
}
});
esto puede funcionar, pero almacenar la contraseña en dynamoDB puede tener problemas, considerando la seguridad. en su lugar, podemos intentar así:
opción n. ° 1: – el usuario se registra con nombre de usuario y contraseña.
- configurar los activadores cognito: podemos usar funciones lambda.
- A. Crear desafío de autenticación B. Definir desafío de autenticación C. Verificar la respuesta de desafío de autenticación
- la aplicación cliente debe implementar el flujo de autenticación CUSTOM_CHALLENGE.
-
pida al usuario que ingrese el número de teléfono registrado, páselo en el campo de nombre de usuario. El activador B comprenderá la solicitud y pasará el flujo al activador A, el activador A generará un código aleatorio 5. Utilice el servicio AWS SNS para enviar SMS al número de teléfono móvil del usuario
- El disparador C validará la OTP y permitirá que los puntos de inicio de sesión consideren: a. configurar el número de teléfono como alias (seleccione Permitir también iniciar sesión con un número de teléfono verificado) b. hacer que el campo del número de teléfono sea verificable (esto permite al usuario recibir OTP)
opción n. ° 1: – el usuario se registra sin nombre de usuario y contraseña.
configuración cognito
- configurar el número de teléfono como alias (seleccione Permitir también iniciar sesión con un número de teléfono verificado)
- hacer que el campo del número de teléfono sea verificable (esto permite al usuario recibir OTP)
- durante el registro, no le pida al usuario que proporcione el nombre de usuario y la contraseña, solo pregunte el número de teléfono
- generar UUID para que el nombre de usuario y la contraseña sean únicos y pasarlos a cognito junto con el número de teléfono
- Cognito envía el código OTP al usuario para la confirmación de la cuenta.
- para el número de teléfono con activadores de configuración de inicio de sesión OTP como se explica en la opción anterior.
para el código de desencadenadores, consulte el grupo cognito de AWS con múltiples opciones de inicio de sesión