Describe the bug
Whenever Auth.currentSession() is called, it will do a request to https://cognito-idp.us-east-1.amazonaws.com/ (AWSCognitoIdentityProviderService.GetUser). I think session should be cached until it expires.
To Reproduce
Steps to reproduce the behavior:
Call:
let session = await Auth.currentSession();
Check network tab in (say) Chrome and see new request to https://cognito-idp.us-east-1.amazonaws.com/
Headers:
Content-Type: application/x-amz-json-1.1
DNT: 1
Origin: http://localhost:3000
Referer: http://localhost:3000/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
X-Amz-Target: AWSCognitoIdentityProviderService.GetUser
X-Amz-User-Agent: aws-amplify/0.1.x js
Expected behavior
Auth.currentSession() returns cached version until it has expired. Token info does get stored in local storage.
Additional context
aws-amplify:1.14
aws-amplify-react: 2.0.5
config:
Amplify.configure({
Auth: {
mandatorySignIn: true,
identityPoolId: xxx,
region: xxx,
userPoolId: xxx,
userPoolWebClientId: xxx,
},
Analytics: {
disabled: true
}
});
@bh213 thanks for you feedback. I agree that we should provide an option for the user to get the user/session only from the cache without sending a request to Cognito. This would also allow us to let Auth module work under offline scenario. Mark as feature request.
@powerful23 Is there a best practice on how to cache idToken.jwtToken
that would also properly handle signout/switch user scenario?
From my debugging it seems idToken gets stored in local storage while user data (attributes and such) are always refreshed using AWSCognitoIdentityProviderService.GetUser
. So just loading id from storage might actually work but unfortunately there is no expire date (except encoded in jwt)...
I am facing this issue too, there are a lot of calls to Cognito when calling currentUserInfo(), sometimes, there are 6 requests. Hopefully, we can fix this issue soon.
Just a reminder: "@aws-amplify/auth": "1.0.3"
didn't make a request to Cognito servers. It returned a cached session. We are really missing this behaviour in the latest version.
My current workaround:
async function currentIdentity() {
const cachePrefix = `CognitoIdentityServiceProvider.${environment.cognito.clientId}`;
const lastUser = localStorage.getItem(`${cachePrefix}.LastAuthUser`);
if (lastUser == null) return null;
const idToken = localStorage.getItem(`${cachePrefix}.${lastUser}.idToken`);
if (idToken == null) throw Error('Failed to read IdToken from cache!');
const identity = JSON.parse(atob(idToken.split('.')[1]));
const expires = identity.exp;
const clockDrift = Number(localStorage.getItem(`${cachePrefix}.${lastUser}.clockDrift`) || 0);
const now = Math.ceil(Date.now() / 1000);
if (expires + clockDrift < now) {
const session = await Auth.currentSession();
if (session == null) return null;
return session.getIdToken().decodePayload();
}
return identity;
}
The last if
is there just for the case when Amplify is already trying to refresh the token. But to be honest, I'm not sure if Auth.currentSession()
returns a new token or not. However, it is an edge case so it is probably enough for now.
I faced the same issue and found the cause:
For my case, I need only fresh JWT for API requests, so, I fixed this issue in the following way:
import { CognitoUserPool } from 'amazon-cognito-identity-js';
import AWSConfig from './AwsConfig';
function getUserSession() {
const NO_USER_ERROR_MESSAGE = 'Could not find the cognito user';
return new Promise((resolve, reject) => {
const USER_POOL_CONFIG = {
UserPoolId: AWSConfig.UserPoolId,
ClientId: AWSConfig.ClientId
};
const userPool = new CognitoUserPool(USER_POOL_CONFIG);
const cognitoUser = userPool.getCurrentUser();
if (cognitoUser) {
cognitoUser.getSession((err, session) => {
if (!err) {
resolve(session);
} else {
reject(err);
}
});
} else {
reject(new Error(NO_USER_ERROR_MESSAGE));
}
});
}
I just removed the code that calls the server every time and used the 'amazon-cognito-identity-js' library directly. getSession() should refresh token automatically. I hope this can help someone
@powerful23 is there any ETA for this feature?
@powerful23 Please consider filing this as a bug. The implementation leaks HTTP requests, which is obviously not intended. IME it is not a feature to have unintended behavior removed.
I think so too @lgrapenthin!
This is not intended and that should be a bug. Do we just need a PR or who is in charge of getting this done? /cc @powerful23
Is there any way of not having to cache the Authentication token yourself currently? We have quite a few requests on a dashboard like page and this is driving our cognito requests into rate limitation by Amplify. This is really an issue :/
Maintainers? How can we help? Should we provide a PR?
@kjellski hey we just had an internal discussion around this issue. We will take an action to resolve this in the next two days.
@powerful23 wonderful news! Thank you a lot for considering this a priority and fixing it ASAP! Keep up the good work!
Most helpful comment
@powerful23 Please consider filing this as a bug. The implementation leaks HTTP requests, which is obviously not intended. IME it is not a feature to have unintended behavior removed.