tutorial libreria cognito aws amazon-web-services aws-lambda amazon-cognito

amazon web services - libreria - Grupo de usuarios de Cognito: cómo actualizar el token de acceso utilizando el token de actualización



jwt java (5)

Estoy usando el grupo de usuarios de Cognito para autenticar a los usuarios en mi sistema. Una autenticación exitosa proporciona un token de ID (JWT), un token de acceso (JWT) y un token de actualización. La documentación aquí, http://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html , menciona claramente que el token de actualización puede ser Se utiliza para actualizar el token de acceso, pero no menciona cómo. Mi pregunta es una vez que mi token de acceso caduque, ¿cómo uso el token de actualización almacenado para actualizar mi token de acceso nuevamente?

Busqué a través del javascript sdk y no pude encontrar ningún método para hacer lo mismo. Definitivamente me he perdido algo.

También pensé en esto a través de una función Lambda que toma el token de acceso y el token de actualización y responde con un token de acceso actualizado. Sería genial si alguien puede arrojar algo de luz sobre esto.

Gracias


Actualizar una sesión con el SDK del navegador amazon-cognito-identity-js; la mayoría lo hace por usted, y a menos que esté haciendo algo inusual, no necesitará manejar el token de actualización directamente. Esto es lo que necesitas saber:

Supongamos que ha creado una instancia del grupo de usuarios de esta manera:

const userPool = new AmazonCognitoIdentity.CognitoUserPool({ UserPoolId: USER_POOL_ID, ClientId: USER_POOL_CLIENT_ID });

Para encontrar el último nombre de usuario autenticado, debe hacer esto:

const cognitoUser = cognitoUserPool.getCurrentUser();

Si encuentra uno, cognitoUser no será nulo, y puede hacer esto, que actualizará sus tokens detrás de escena si es necesario:

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 no desea que estos tokens permanezcan en el almacenamiento local, puede:

cognitoUser.signOut();

La forma en que funciona es que, después de una autenticación exitosa, el navegador almacenará sus tokens JWT, incluido ese token de actualización. Los almacena de forma predeterminada en el almacenamiento local de su navegador, aunque puede proporcionar su propio objeto de almacenamiento si lo desea. De forma predeterminada, el token de actualización es válido para 30d, pero es una propiedad (RefreshTokenValidity) de su UserPoolClient, que puede cambiar. Cuando haga lo anterior, getSession () verá primero si los tokens que tiene almacenados existen y siguen siendo válidos; si no, intentará utilizar cualquier refreshToken que encuentre allí para autenticarse en una nueva sesión.

La documentación http://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html indica que los SDK de iOS y Android harán esto por Tú, aunque no los he usado, no puedo responder por eso.


Aquí hay un ejemplo de cómo hacerlo con JavaScript en el lado del servidor usando 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? } });

Puede ver un ejemplo completo de trabajo en la publicación de mi blog Cómo autenticar a los usuarios con Tokens usando Cognito .


El Javascript sdk maneja la actualización interna de los tokens. Cuando se llama "getSession" para obtener tokens, en ausencia de cualquier acceso en caché válido y tokens de identificación, el SDK usa el token de actualización para obtener nuevos tokens de acceso e identificación. Invoca la autenticación del usuario, requiriendo que el usuario proporcione el nombre de usuario y la contraseña, solo cuando el token de actualización también haya caducado.

Saludos, Mahesh


He estado luchando con esto también en Javascript. Aquí está mi solución, se basa en github.com/aws/amazon-cognito-identity-js PERO no se basa en el almacenamiento, por lo que puede usarla en una función lambda si lo desea. Edición: Código fijo, gracias a Crayones.

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 })


Si se encuentra en una situación en la que Cognito Javascript SDK no funcionará para sus propósitos, aún puede ver cómo maneja el proceso de actualización en la fuente de SDK :

En refreshSession puede ver que se llama al punto final de Cognito InitiateAuth con el conjunto de REFRESH_TOKEN_AUTH para el valor de AuthFlow y un objeto pasado como el valor de AuthParameters .

Ese objeto deberá configurarse para satisfacer las necesidades de su grupo de usuarios. Específicamente, es posible que tenga que pasar su SECRET_HASH si su ID de cliente de la aplicación objetivo tiene un secreto de cliente de la aplicación asociado. Las aplicaciones de usuario del grupo de usuarios creadas para su uso con el SDK de Javascript actualmente no pueden contener un secreto de cliente, por lo que no se requiere un SECRET_HASH para conectarse con ellos.

Otra advertencia que podría hacerte un bucle es si tu grupo de usuarios está configurado para recordar dispositivos y no pasas el DEVICE_KEY junto con tu REFRESH_TOKEN . La API de Cognito actualmente devuelve un error de "Token de actualización no válido" si está pasando el RefreshToken sin pasar también su DeviceKey . Este error se devuelve incluso si está pasando un RefreshToken válido. El hilo vinculado arriba ilumina eso, aunque espero que AWS actualice su manejo de errores para que sea menos críptico en el futuro.

Como se explica en ese hilo, si está utilizando AdminInitiateAuth junto con ADMIN_NO_SRP_AUTH , su carga útil de respuesta de autenticación exitosa no contiene actualmente NewDeviceMetadata ; lo que significa que no DeviceKey que pasar ningún DeviceKey cuando intentes actualizar tus tokens.

Mi aplicación requiere una implementación en Python, así que aquí hay un ejemplo que me funcionó:

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