Shailesh
Shailesh

Reputation: 2276

How to refresh IdToken from AWS Lambda

I've set up a Lambda trigger for an SQS queue, so that the Lambda function is called when the queue gets any new messages.

The Lambda function (in Python) is being used to call an API endpoint, which requires a AWS Cognito IdToken, like this:

api_endpoint = 'https://api.us-east-1.amazonaws.com/v1/xyz'
headers = {"Authorization": "Bearer id_token_here"}

However after 24 hours, the IdToken gets expired and I've generate a new one using Cognito admin-initiate-auth.

How can I manage this in Lambda? I can't add the admin-initiate-auth command in the lambda function because then it'll run it for each message, which I believe isn't ideal.

What is the best way to handle this? Is there a way in which the IdToken keeps getting refreshed whenever it's expired or about to expire, without failing the API request (due to expired token)?

Upvotes: 0

Views: 1473

Answers (1)

samtoddler
samtoddler

Reputation: 9635

You can simply refreshSession with InitiateAuth API Call with REFRESH_TOKEN_AUTH.

Once you get the token you store it in AWS Secrets Manager and then fetch it from there on each lambda invocation. If the token you fetched from secrets manager is not valid anymore you simply refresh and update secrets manager's value as well.

Below is some sample code

    def initiate_auth(client, username, password):
    ...

        resp = client.admin_initiate_auth(
                    UserPoolId=USER_POOL_ID,
                    ClientId=CLIENT_ID,
                    AuthFlow='ADMIN_NO_SRP_AUTH',
                    AuthParameters={
                        'USERNAME': username,
                        'SECRET_HASH': secret_hash,
                        'PASSWORD': password,
                    },
                    ClientMetadata={
                    'username': username,
                    'password': password,
                })

    def lambda_handler(event, context):
    client = boto3.client('cognito-idp')
    ...
    resp, msg = initiate_auth(client, username, password)
    ...
    if resp.get("AuthenticationResult"):
        return {'message': "success", 
                "error": False, 
                "success": True, 
                "data": {
                "id_token": resp["AuthenticationResult"]["IdToken"],
        "refresh_token": resp["AuthenticationResult"]["RefreshToken"],
        "access_token": resp["AuthenticationResult"]["AccessToken"],
        "expires_in": resp["AuthenticationResult"]["ExpiresIn"]
        "token_type": resp["AuthenticationResult"]["TokenType"]
                }}
        else:
        ....

Upvotes: 1

Related Questions