J'utilise un groupe d'utilisateurs Cognito pour authentifier les utilisateurs de mon système. Une authentification réussie donne un jeton d’identification (JWT), un jeton d’accès (JWT) et un jeton d’actualisation. La documentation ici, http://docs.aws.Amazon.com/cognito/latest/developerguide/Amazon-cognito-user-pools-using-tokens-with-identity-providers.html , mentionne clairement que le Le jeton d'actualisation peut être utilisé pour actualiser le jeton d'accès, mais ne précise pas comment. Ma question est la suivante: une fois mon jeton d'accès arrivé à expiration, comment utiliser le jeton d'actualisation stocké pour actualiser à nouveau mon jeton d'accès?
J'ai cherché dans le sdk javascript et je n'ai trouvé aucune méthode pour faire de même. J'ai définitivement raté quelque chose.
J'y pensais aussi via une fonction Lambda qui prend le jeton d'accès et le jeton d'actualisation et répond avec un jeton d'accès actualisé. Ce serait formidable si quelqu'un peut jeter un peu de lumière à ce sujet.
Merci
Si vous êtes dans une situation où le SDK Javascript de Cognito ne fonctionnera pas pour vous, vous pouvez toujours voir comment il gère le processus d'actualisation dans le fichier source du SDK :
Vous pouvez voir dans refreshSession
que le point de terminaison Cognito InitiateAuth est appelé avec REFRESH_TOKEN_AUTH
défini pour la valeur AuthFlow
et un objet transmis en tant que valeur AuthParameters
.
Cet objet devra être configuré pour répondre aux besoins de votre groupe d'utilisateurs. Plus précisément, vous devrez peut-être transmettre votre SECRET_HASH
si l'ID de votre client d'application ciblée est associé à un secret client d'application. Les applications client de pool d'utilisateurs créées pour être utilisées avec le SDK Javascript ne peuvent actuellement pas contenir de secret client. Par conséquent, un SECRET_HASH
n'est pas nécessaire pour se connecter avec elles.
Une autre mise en garde qui pourrait vous faire perdre une boucle est si votre groupe d'utilisateurs est configuré pour mémoriser les périphériques et si vous ne transmettez pas le DEVICE_KEY
avec votre REFRESH_TOKEN
. L’API de Cognito renvoie actuellement un "jeton d’actualisation non valide" si vous transmettez la RefreshToken
sans transmettre également votre DeviceKey
. Cette erreur est renvoyée même si vous transmettez une RefreshToken
valide. Le fil de liaison ci-dessus illustre cela, même si j'espère que AWS mettra à jour leur traitement des erreurs pour qu'il soit moins crypté à l'avenir.
Comme indiqué dans ce fil de discussion, si vous utilisez AdminInitiateAuth avec ADMIN_NO_SRP_AUTH
, le contenu de votre réponse d'authentification réussie ne contient actuellement pas NewDeviceMetadata
; ce qui signifie que vous n'aurez pas de variable DeviceKey
à passer lorsque vous tenterez d'actualiser vos jetons.
Mon application appelle à une implémentation en Python, alors voici un exemple qui a fonctionné pour moi:
def refresh_token(self, username, refresh_token):
try:
return client.initiate_auth(
ClientId=self.client_id,
AuthFlow='REFRESH_TOKEN_AUTH',
AuthParameters={
'REFRESH_TOKEN': refresh_token,
'SECRET_HASH': self.get_secret_hash(username)
// Note that SECRET_HASH is missing from JSDK
// Note also that DEVICE_KEY is missing from my example
}
)
except botocore.exceptions.ClientError as e:
return e.response
Le SDK Javascript gère l'actualisation interne des jetons. Lorsque vous appelez "getSession" pour obtenir des jetons, en l'absence de tout jeton d'accès et d'identifiant valide mis en cache, le SDK utilise le jeton d'actualisation pour obtenir de nouveaux jetons d'accès et d'identifiant. Il appelle l'authentification de l'utilisateur, obligeant l'utilisateur à fournir le nom d'utilisateur et le mot de passe uniquement lorsque le jeton d'actualisation est également arrivé à expiration.
Cordialement, Mahesh
Actualisation d'une session avec le SDK du navigateur Amazon-cognito-identity-js; il le fait principalement pour vous, et à moins que vous ne fassiez quelque chose d'inhabituel, vous n'avez pas besoin de gérer le jeton d'actualisation directement. Voici ce que vous devez savoir:
Supposons que vous avez instancié le groupe d'utilisateurs comme suit:
const userPool = new AmazonCognitoIdentity.CognitoUserPool({
UserPoolId: USER_POOL_ID,
ClientId: USER_POOL_CLIENT_ID
});
Pour trouver le dernier nom d'utilisateur authentifié, procédez comme suit:
const cognitoUser = cognitoUserPool.getCurrentUser();
S'il en trouve un, cognitoUser sera non nul et vous pouvez le faire, ce qui actualisera vos jetons dans les coulisses si nécessaire:
cognitoUser.getSession(function(err, data) {
if (err) {
// Prompt the user to reauthenticate by hand...
} else {
const cognitoUserSession = data;
const yourIdToken = cognitoUserSession.getIdToken().jwtToken;
const yourAccessToken = cognitoUserSession.getAccessToken().jwtToken;
}
});
Si vous ne voulez pas que ces jetons persistent dans le stockage local, vous pouvez:
cognitoUser.signOut();
Cela fonctionne comme suit: après une authentification réussie, le navigateur stockera vos jetons JWT, y compris ce jeton d'actualisation. Il les stocke par défaut dans la mémoire de stockage locale de votre navigateur, bien que vous puissiez fournir votre propre objet de stockage si vous le souhaitez. Par défaut, le jeton d'actualisation est valide pour 30d, mais il s'agit d'une propriété (RefreshTokenValidity) de votre UserPoolClient, que vous pouvez modifier. Lorsque vous effectuez cette opération, getSession () vérifie d’abord si les jetons stockés existent et sont toujours valides; sinon, il essaiera d'utiliser tout ce que refreshToken y trouve pour vous authentifier dans une nouvelle session.
La documentation http://docs.aws.Amazon.com/cognito/latest/developerguide/Amazon-cognito-user-pools-using-tokens-with-identity-providers.html indique que les SDK iOS et Android le fera pour vous, bien que je n’ai pas utilisé ceux-ci, je ne peux donc pas en témoigner.
J'ai aussi eu du mal avec cela en Javascript. Voici ma solution, elle est basée sur https://github.com/aws/Amazon-cognito-identity-js MAIS elle ne repose pas sur le stockage, vous pouvez donc l'utiliser dans une fonction lambda si vous le souhaitez. Edit: Code fixe, grâce à Crayons
const userPool = new AWSCognito.CognitoUserPool({
UserPoolId: <COGNITO_USER_POOL>,
ClientId: <COGNITO_APP_ID>
})
userPool.client.makeUnauthenticatedRequest('initiateAuth', {
ClientId: <COGNITO_APP_ID>,
AuthFlow: 'REFRESH_TOKEN_AUTH',
AuthParameters: {
'REFRESH_TOKEN': <REFRESH_TOKEN> // client refresh JWT
}
}, (err, authResult) => {
if (err) {
throw err
}
console.log(authResult) // contains new session
})
Voici un exemple de la façon de le faire avec JavaScript côté serveur en utilisant Node.js.
const AccessToken = new CognitoAccessToken({ AccessToken: tokens.accessToken });
const IdToken = new CognitoIdToken({ IdToken: tokens.idToken });
const RefreshToken = new CognitoRefreshToken({ RefreshToken: tokens.refreshToken });
const sessionData = {
IdToken: IdToken,
AccessToken: AccessToken,
RefreshToken: RefreshToken
};
const userSession = new CognitoUserSession(sessionData);
const userData = {
Username: email,
Pool: this.userPool
};
const cognitoUser = new CognitoUser(userData);
cognitoUser.setSignInUserSession(userSession);
cognitoUser.getSession(function (err, session) { // You must run this to verify that session (internally)
if (session.isValid()) {
// Update attributes or whatever else you want to do
} else {
// TODO: What to do if session is invalid?
}
});
Vous pouvez voir un exemple de travail complet dans mon article de blog Comment authentifier les utilisateurs avec Tokens à l'aide de Cognito .
Si vous avez un jeton d'actualisation, vous pouvez obtenir un nouvel accès, un nouvel identifiant et un jeton d'actualisation en adressant simplement cette simple POST demande à cognito:
POST https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/token >
Content-Type='application/x-www-form-urlencoded'
Authorization=Basic aSdxd892iujendek328uedj
grant_type=refresh_token&
client_id=djc98u3jiedmi283eu928&
refresh_token=REFRESH_TOKEN
Vous obtiendrez la réponse suivante:
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token":"eyJz9sdfsdfsdfsd",
"refresh_token":"dn43ud8uj32nk2je",
"id_token":"dmcxd329ujdmkemkd349r",
"token_type":"Bearer",
"expires_in":3600
}