Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Sample code: how to refresh session of Cognito User Pools with Node.js and Express
const AWS = require('aws-sdk');
const CognitoUserPool = require('amazon-cognito-identity-js-node').CognitoUserPool;
const CognitoUserSession = require('amazon-cognito-identity-js-node').CognitoUserSession;
const CognitoUser = require('amazon-cognito-identity-js-node').CognitoUser;
const CognitoIdToken = require('amazon-cognito-identity-js-node').CognitoIdToken;
const CognitoAccessToken = require('amazon-cognito-identity-js-node').CognitoAccessToken;
const CognitoRefreshToken = require('amazon-cognito-identity-js-node').CognitoRefreshToken;
const cfg = require('config').config;
const COGNITO_IDENTITY_POOL_ID = cfg.COGNITO_IDENTITY_POOL_ID;
const COGNITO_USER_POOL_ID = cfg.COGNITO_USER_POOL_ID;
const COGNITO_CLIENT_ID = cfg.COGNITO_CLIENT_ID;
const AWS_API_GATEWAY_HOSTNAME = cfg.AWS_API_GATEWAY_HOSTNAME;
const AWS_REGION = cfg.AWS_REGION;
// Redirect to "/login" if a user is not logged-in.
exports.authorize = require('connect-ensure-login').ensureLoggedIn('/login');
exports.authorizeUser = function(req, res, next) {
AWS.config.region = AWS_REGION;
const tokens = req.user.tokens;
AWS.config.credentials = getCognitoIdentityCredentials(tokens);
AWS.config.credentials.get(function(err) {
if (err) throw err;
req.session.identityId = AWS.config.credentials.identityId;
const credentials = AWS.config.credentials.data.Credentials;
req.session.AWSCredentials = getAWSCredentials(credentials);
next();
});
};
exports.checkTokenExpiration = function(req, res, next) {
const AccessToken = new CognitoAccessToken({AccessToken: req.user.tokens.accessToken});
const IdToken = new CognitoIdToken({IdToken: req.user.tokens.idToken});
const RefreshToken = new CognitoRefreshToken({RefreshToken: req.user.tokens.refreshToken});
const sessionData = {
IdToken: IdToken,
AccessToken: AccessToken,
RefreshToken: RefreshToken
};
const cachedSession = new CognitoUserSession(sessionData);
if (cachedSession.isValid()) {
next();
} else {
cognitoUser = getCognitoUser(req);
cognitoUser.refreshSession(RefreshToken, (err, session) => {
if (err) throw err;
const tokens = getTokens(session);
AWS.config.credentials = getCognitoIdentityCredentials(tokens);
AWS.config.credentials.get(function() {
const credentials = AWS.config.credentials.data.Credentials;
req.session.AWSCredentials = getAWSCredentials(credentials);
next();
});
});
}
};
getCognitoUser = function(req) {
const poolData = {
UserPoolId : COGNITO_USER_POOL_ID,
ClientId : COGNITO_CLIENT_ID
};
const userPool = new CognitoUserPool(poolData);
const userData = {
Username : req.user.email,
Pool : userPool
};
return new CognitoUser(userData);
};
getTokens = function(session) {
return {
accessToken: session.getAccessToken().getJwtToken(),
idToken: session.getIdToken().getJwtToken(),
refreshToken: session.getRefreshToken().getToken()
};
};
getCognitoIdentityCredentials = function(tokens) {
const loginInfo = {};
loginInfo[`cognito-idp.${AWS_REGION}.amazonaws.com/${COGNITO_USER_POOL_ID}`] = tokens.idToken;
const params = {
IdentityPoolId: COGNITO_IDENTITY_POOL_ID,
Logins: loginInfo
};
return new AWS.CognitoIdentityCredentials(params);
};
getAWSCredentials = function(credentials) {
return {
accessKey: credentials.AccessKeyId,
secretKey: credentials.SecretKey,
sessionToken: credentials.SessionToken,
region: AWS_REGION,
invokeUrl: 'https://' + AWS_API_GATEWAY_HOSTNAME
};
};
@ispulkit

This comment has been minimized.

Copy link

@ispulkit ispulkit commented Jan 12, 2018

Thanks!

@coreylight

This comment has been minimized.

Copy link

@coreylight coreylight commented Jan 14, 2018

Thank you!

@anildbest83

This comment has been minimized.

Copy link

@anildbest83 anildbest83 commented May 3, 2018

When cachedSession.isValid() is false you get the Cognito User using user email. Can't we get the tokens again with refresh token only?

@jayasimhaprasad

This comment has been minimized.

Copy link

@jayasimhaprasad jayasimhaprasad commented Jun 29, 2018

i was searching for this code for the past 2 days. Thank you for taking time to put this code up #

@ubugnu

This comment has been minimized.

Copy link

@ubugnu ubugnu commented Aug 28, 2018

Question: in the official documentation (or better said: official examples) Use case 32, they use AWS.config.credentials.needsRefresh() to test session validity, you are using cachedSession.isValid().
I've tried the first, I got a session that needs refresh every time I refresh a brower window.

@ToddHoff

This comment has been minimized.

Copy link

@ToddHoff ToddHoff commented Feb 10, 2019

Is there a way to just pass in the tokens from the web client down to the lambda function and make 'amazon-cognito-identity-js' use those tokens without needing the login name?

@afraz-khan

This comment has been minimized.

Copy link

@afraz-khan afraz-khan commented Jan 3, 2020

Can you explain, how it is being checked that session is valid or not. Because, right in yr code, i dont see any productive use of isValid().

@vaibhavsonu

This comment has been minimized.

Copy link

@vaibhavsonu vaibhavsonu commented Nov 28, 2020

Can you explain, how it is being checked that session is valid or not. Because, right in yr code, I don't see any productive use of isValid().

Yes, it has productive use. Access id and token come with an expiration time which can be configured from the console.

Here is the code behind isvalid(). It checks expiration time.

 isValid() {
const now = Math.floor(new Date() / 1000);

return now < this.accessToken.getExpiration() && now < this.idToken.getExpiration();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment