Reputation: 795
i'm implementing a node.js backend using the amazon-cognito-identity-js.
I want to create a login(username, password) and refreshToken(token) APIs.
This is my code:
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);
},
});
}
This function returns an accessToken and a refreshToken without errors.
After this, i have implemented this function:
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)) });
}
but passing the refreshToken previously retrieved it returns an:
NotAuthorizedException: Invalid Refresh Token.
Can anyone tell me what is the correct backend implementation of these 2 apis ?
Upvotes: 3
Views: 5860
Reputation: 795
I solved in this way:
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);
}
}
I used aws-amplify for login and aws-sdk/client-cognito-identity-provider for other operations.
NotAuthorizedException: Invalid Refresh Token
error message was returned because the device tracking option was enabled in Cognito settings.
It' s incredible for a service provided by AWS to give wrong error messages and very little documentation about it
Upvotes: 3