Reputation: 107
I use below (simplified) code with AWS libraries to get access to AWS resources like DynamoDB through browser javascript. The ID/access tokens expire in 60 minutes; the refresh tokens in 30 days (the Cognito defaults). This works mostly fine. AWS amplify automatically refreshes the tokens under the hood with each new API call.
What I have been wondering about – and I couldn't find clear answers here or elsewhere - is how to get tokens refreshed if the user has been idle for more than 60 minutes, and then sends a new query, such as with below function queryTable(). When that happens the access token has expired and the function throws an error. This could be remedied by calling refreshSession() and initializeAWS() before or in every queryTable() call. But creating a new dynamoDB client for every call seems a bit overkill or inelegant. Are there better ways to deal with this issue?
import { Amplify, Auth } from 'aws-amplify';
import { fromCognitoIdentityPool } from "@aws-sdk/credential-providers";
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, QueryCommand } from "@aws-sdk/lib-dynamodb";
let token;
let ddbDocClient;
Amplify.configure({
Auth: {
region: REGION,
userPoolId: USERPOOLID,
userPoolWebClientId: USERPOOLWEBCLIENTID,
},
})
;(async () => {
try {
await refreshSession();
initializeAWS();
} catch (e) {
console.warn("You need to log in first!");
}
})()
async function refreshSession() {
// Get current session
try {
const session = await Auth.currentSession();
token = session.getIdToken().getJwtToken();
} catch (e) {
console.warn(e);
}
}
async function initializeAWS() {
// Get current session
try {
const config = {
region: REGION,
credentials: fromCognitoIdentityPool({
identityPoolId: IDENTITYPOOLID,
clientConfig: { region: REGION },
logins: {
[`cognito-idp.${REGION}.amazonaws.com/${USERPOOLID}`]: token,
},
}),
};
const ddbClient = new DynamoDBClient(config);
ddbDocClient = DynamoDBDocumentClient.from(ddbClient);
} catch (e) {
console.warn(e);
}
}
async function queryTable(PK){
const params = {
TableName: "HES",
KeyConditionExpression: "#PK = :PK",
ExpressionAttributeNames: {
"#PK": "PK"
},
ExpressionAttributeValues: {
":PK": PK
},
}
try {
const data = await ddbDocClient.send(new QueryCommand(params));
console.log("Result Query\n",data.Items)
} catch (e) {
console.warn(e)
}
}
$("#queryTestButton").on("click", () => {
queryTable("test")
})
Upvotes: 2
Views: 298