Skip to content

Instantly share code, notes, and snippets.

@heridev
Last active December 7, 2024 14:42
Show Gist options
  • Save heridev/a5287e9c91e105ac3f8d4700c2a5cc99 to your computer and use it in GitHub Desktop.
Save heridev/a5287e9c91e105ac3f8d4700c2a5cc99 to your computer and use it in GitHub Desktop.
Determine if AWS Cognito V6 Generation 2 does not refresh accessToken automatically as it was the case for v5(pre v6)

First of all you need to change the expiration for access Token and ID token

Within the Cognito User Pool configure that to be 5 minutes(300 seconds) and both values should match, this way you can make the test faster than waiting for the default 1 hour expiration.

  1. Open your AWS Cognito console.
  2. Go to your user pool and then App integration.
  3. Scroll down to App clients(probably your web client) and click edit

NOTE: Make the update for any App clients you see in your user pool, in my case it was for the app client and web client

image

Then you can try some of these scripts

Trying a sequence to validate behavior

// Run this sequence to test
const testSequence = async () => {
  // Get initial token
  const session1 = await fetchAuthSession();
  const token1 = session1.tokens?.accessToken?.toString();
  
  // Wait 5.5 minutes
  await new Promise(r => setTimeout(r, 5.5 * 60 * 1000));
  
  // Get token again
  const session2 = await fetchAuthSession();
  const token2 = session2.tokens?.accessToken?.toString();
  
  // Compare tokens
  console.log('Tokens are identical:', token1 === token2);
  
  // Try an API call
  await testApiCall();
};

Another script to try

import { fetchAuthSession } from 'aws-amplify/auth';
import { Hub } from 'aws-amplify/utils';

// Utility to decode JWT token
const decodeToken = (token) => {
  try {
    const base64Url = token.split('.')[1];
    const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
    return JSON.parse(window.atob(base64));
  } catch (error) {
    console.error('Error decoding token:', error);
    return null;
  }
};

// Function to monitor token refresh behavior
const monitorTokenRefresh = async () => {
  // Setup Hub listener for auth events
  Hub.listen('auth', ({ payload }) => {
    console.log('Auth Event:', payload.event);
    if (payload.event === 'tokenRefresh') {
      console.log('Token refresh detected through Hub event');
    }
  });

  try {
    // Get initial session
    console.log('Getting initial session...');
    const initialSession = await fetchAuthSession();
    const initialToken = initialSession.tokens?.accessToken?.toString();
    const initialDecoded = decodeToken(initialToken);
    console.log('Initial token exp:', new Date(initialDecoded.exp * 1000).toISOString());
    console.log('Initial token iat:', new Date(initialDecoded.iat * 1000).toISOString());

    // Wait for 6 minutes (assuming 5-minute expiration)
    console.log('Waiting for 6 minutes...');
    await new Promise(resolve => setTimeout(resolve, 6 * 60 * 1000));

    // Get session again without force refresh
    console.log('Getting session after delay (without force refresh)...');
    const laterSession = await fetchAuthSession();
    const laterToken = laterSession.tokens?.accessToken?.toString();
    const laterDecoded = decodeToken(laterToken);
    console.log('Later token exp:', new Date(laterDecoded.exp * 1000).toISOString());
    console.log('Later token iat:', new Date(laterDecoded.iat * 1000).toISOString());

    // Compare tokens
    console.log('Tokens are the same:', initialToken === laterToken);
    
    // Try with force refresh
    console.log('Getting session with force refresh...');
    const forcedSession = await fetchAuthSession({ forceRefresh: true });
    const forcedToken = forcedSession.tokens?.accessToken?.toString();
    const forcedDecoded = decodeToken(forcedToken);
    console.log('Forced token exp:', new Date(forcedDecoded.exp * 1000).toISOString());
    console.log('Forced token iat:', new Date(forcedDecoded.iat * 1000).toISOString());

    // Compare with forced refresh token
    console.log('Forced token is different from initial:', initialToken !== forcedToken);
    console.log('Forced token is different from later:', laterToken !== forcedToken);

  } catch (error) {
    console.error('Error during token monitoring:', error);
  }
};

// Example usage in a React component
const TokenTestComponent = () => {
  useEffect(() => {
    monitorTokenRefresh();
  }, []);

  return <div>Check console for token refresh monitoring</div>;
};

// Use this function to make an API call and check token behavior
const testApiCall = async () => {
  try {
    const session = await fetchAuthSession();
    const token = session.tokens?.accessToken?.toString();
    const decoded = decodeToken(token);
    
    console.log('Token used for API call:');
    console.log('Expiration:', new Date(decoded.exp * 1000).toISOString());
    console.log('Issued at:', new Date(decoded.iat * 1000).toISOString());
    
    // Make your API call here
    const response = await fetch('your-api-endpoint', {
      headers: {
        Authorization: `Bearer ${token}`
      }
    });
    
    return response;
  } catch (error) {
    console.error('API call error:', error);
    throw error;
  }
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment