Estoy implementando un backend de node.js usando amazon-cognito-identity-js.
Quiero crear un inicio de sesión (nombre de usuario, contraseña) y API de actualización de token (token).
Este es mi código:
import { AuthenticationDetails, CognitoUser, CognitoUserPool, CognitoRefreshToken } from "amazon-cognito-identity-js" public loginWithAmazonCognitoIdentity (username: string, password: string){ var authenticationData = { Username : username, Password : password, }; var authenticationDetails = new AuthenticationDetails(authenticationData); var poolData = { UserPoolId : 'eu-north-1_xxxxxx', ClientId : '3al0l3mhcxxxxxqgnp789987' }; var userPool = new CognitoUserPool(poolData); var userData = { Username : username, Pool : userPool }; var cognitoUser = new CognitoUser(userData); const user = cognitoUser.authenticateUser(authenticationDetails, { onSuccess: function (result) { var accessToken = result.getAccessToken().getJwtToken(); console.log("token: " + accessToken); var refresh = result.getRefreshToken().getToken(); console.log("RefreshToken: " + refresh); }, onFailure: function(err) { console.error(err); }, }); }Esta función devuelve un accessToken y un refreshToken sin errores.
Después de esto, he implementado esta función:
public refreshToken(refreshToken) var poolData = { UserPoolId : 'eu-north-1_xxxxxx', ClientId : '3al0l3mhcxxxxxqgnp789987' }; var userPool = new CognitoUserPool(poolData); var userData = { Username : 'lacucudi', Pool : userPool }; var cognitoUser = new CognitoUser(userData); var token = new CognitoRefreshToken({ RefreshToken: refreshToken }) cognitoUser.refreshSession(token, (err, session) => { if (err) {console.log(err)} else console.log('session: ' + JSON.stringify(session)) }); }pero al pasar el refreshToken previamente recuperado, devuelve un:
NotAuthorizedException: token de actualización no válido.
¿Alguien puede decirme cuál es la implementación backend correcta de estas 2 API?
Resolví de esta manera:
import Amplify, { Auth } from "aws-amplify"; import { AdminCreateUserCommand, AdminSetUserPasswordCommand, AuthFlowType, CognitoIdentityProviderClient, CognitoIdentityProviderClientConfig, GetUserCommand, InitiateAuthCommand, MessageActionType, RevokeTokenCommand, } from "@aws-sdk/client-cognito-identity-provider"; public async login(username: string, password: string): Promise<AuthTokens> { if (!username || !password) { throw new HttpException(400, "Please provide both username and password"); } Amplify.configure({ Auth: config.auth }); const user = await Auth.signIn(username, password); if (!user.signInUserSession) { throw new HttpException(500, `Could not authenticate user ${username}`); } const { signInUserSession: { accessToken: { jwtToken: access_token }, idToken: { jwtToken: id_token }, refreshToken: { token: refresh_token }, }, } = user; return { id_token, access_token, refresh_token, }; } public async refresh(refresh_token: string): Promise<AuthTokens> { if (!refresh_token) { throw new HttpException(400, "Please provide a refresh token"); } const refreshTokenAuth = new InitiateAuthCommand({ ClientId: config.auth.userPoolWebClientId, AuthFlow: AuthFlowType.REFRESH_TOKEN_AUTH, AuthParameters: { REFRESH_TOKEN: refresh_token, }, }); const response = await this.client.send(refreshTokenAuth); const { AuthenticationResult: { AccessToken, IdToken }, } = response; return { refresh_token, access_token: AccessToken, id_token: IdToken, }; } public async logout(refreshToken: string): Promise<boolean> { if (!refreshToken) { throw new HttpException(400, "Please provide a refresh token"); } try { const command = new RevokeTokenCommand({ ClientId: config.auth.userPoolWebClientId, Token: refreshToken, }); const response = await this.client.send(command); const { httpStatusCode } = response.$metadata; return httpStatusCode == 200 ?? true; } catch (e) { logger.error(e); throw new HttpException(500, e); } }Usé aws-amplify para iniciar sesión y aws-sdk/client-cognito-identity-provider para otras operaciones.
NotAuthorizedException: token de actualización no válido
se devolvió un mensaje de error porque la opción de seguimiento del dispositivo estaba habilitada en la configuración de Cognito.
Es increíble que un servicio proporcionado por AWS brinde mensajes de error incorrectos y muy poca documentación al respecto.