web-dev-qa-db-de.com

Cognito User Pool: So aktualisieren Sie Access Token mithilfe von Refresh Token

Ich verwende den Cognito-Benutzerpool, um Benutzer in meinem System zu authentifizieren. Bei einer erfolgreichen Authentifizierung erhalten Sie ein ID-Token (JWT), ein Access-Token (JWT) und ein Aktualisierungs-Token. Die Dokumentation hier, http://docs.aws.Amazon.com/cognito/latest/developerguide/Amazon-cognito-user-pools-using-tokens-with-identity-providers.html , weist klar darauf hin, dass die Aktualisierungstoken kann verwendet werden, um das Zugriffstoken zu aktualisieren, erwähnt jedoch nicht, wie. Meine Frage ist, wenn mein Zugriffstoken abgelaufen ist. Wie verwende ich das gespeicherte Aktualisierungstoken, um mein Zugriffstoken erneut zu aktualisieren?

Ich durchsuchte die Javascript-SDK und konnte keine Methode finden, um das gleiche zu tun. Ich habe definitiv etwas vermisst. 

Ich habe auch über eine Lambda-Funktion nachgedacht, die den Zugriffstoken und den Aktualisierungstoken aufnimmt und mit einem aktualisierten Zugriffstoken antwortet. Wäre toll, wenn jemand etwas Licht auf dieses Thema werfen könnte.

Vielen Dank

26
Hardik Shah

Wenn Sie sich in einer Situation befinden, in der das Cognito Javascript SDK für Ihre Zwecke nicht funktioniert, können Sie immer noch sehen, wie es den Aktualisierungsvorgang in der SDK-Quelle abwickelt :

Sie können in refreshSession sehen, dass der Cognito InitiateAuth -Endpunkt mit REFRESH_TOKEN_AUTH für den AuthFlow-Wert aufgerufen wird und ein Objekt als AuthParameters-Wert übergeben wird.

Dieses Objekt muss entsprechend den Anforderungen Ihres Benutzerpools konfiguriert werden. Insbesondere müssen Sie möglicherweise Ihren SECRET_HASH übergeben, wenn Ihre Ziel-App-Client-ID ein zugehöriges App-Client-Geheimnis enthält. Benutzerpool-Client-Apps, die zur Verwendung mit dem Javascript SDK erstellt wurden, können derzeit kein Clientgeheimnis enthalten. Daher ist kein SECRET_HASH erforderlich, um eine Verbindung mit ihnen herzustellen.

Ein weiterer Nachteil, der Sie möglicherweise für eine Schleife auslöst, besteht darin, dass Ihr Benutzerpool auf das Speichern von Geräten eingestellt ist und Sie den DEVICE_KEY nicht zusammen mit Ihrem REFRESH_TOKEN übergeben. Die Cognito-API gibt derzeit einen "Invalid Refresh Token" - Fehler zurück, wenn Sie die RefreshToken übergeben, ohne auch Ihre DeviceKey zu übergeben. Dieser Fehler wird auch dann zurückgegeben, wenn Sie eine gültige RefreshToken übergeben haben. Der oben verlinkte Thread beleuchtet, dass ich hoffe, dass AWS ihre Fehlerbehandlung in Zukunft weniger kryptisch aktualisiert.

Wie in diesem Thread erläutert, enthält Ihre erfolgreiche Authentifizierungsantwort-Nutzlast derzeit nicht NewDeviceMetadata, wenn Sie AdminInitiateAuth zusammen mit ADMIN_NO_SRP_AUTH verwenden. Das bedeutet, dass Sie keine DeviceKey übergeben müssen, um Ihre Tokens zu aktualisieren.

Meine App erfordert eine Implementierung in Python. Hier ein Beispiel, das für mich funktioniert hat:

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
24
afilbert

Die Javascript-SDK übernimmt die interne Aktualisierung der Token. Wenn Sie "getSession" aufrufen, um Token abzurufen, verwendet das SDK das Aktualisierungs-Token, um gültige zwischengespeicherte Zugriffs- und ID-Token zu erhalten, um neue Zugriffs- und ID-Token zu erhalten. Es ruft die Benutzerauthentifizierung auf, und der Benutzer muss nur dann Benutzername und Kennwort angeben, wenn das Aktualisierungstoken ebenfalls abgelaufen ist.

Viele Grüße. Mahesh

18
M Reddy

Aktualisierung einer Sitzung mit dem Browser-SDK von Amazon-cognito-identity-js; Meistens erledigt es dies für Sie, und wenn Sie nichts Ungewöhnliches tun, müssen Sie das Aktualisierungstoken nicht direkt behandeln. Folgendes müssen Sie wissen:

Angenommen, Sie haben den Benutzerpool folgendermaßen instanziiert:

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

Um den letzten authentifizierten Benutzernamen zu finden, führen Sie Folgendes aus:

const cognitoUser = cognitoUserPool.getCurrentUser();

Wenn eine gefunden wird, ist cognitoUser nicht null, und Sie können dies tun, wodurch die Token im Hintergrund aktualisiert werden, falls dies erforderlich ist:

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

Wenn Sie nicht möchten, dass diese Token im lokalen Speicher verbleiben, können Sie:

cognitoUser.signOut();

Es funktioniert so, dass der Browser nach einer erfolgreichen Authentifizierung Ihre JWT-Token einschließlich dieses Aktualisierungstokens speichert. Sie speichert diese standardmäßig im lokalen Speicher in Ihrem Browser. Sie können jedoch auch Ihr eigenes Speicherobjekt bereitstellen. Standardmäßig ist das Aktualisierungstoken für 30d gültig, es ist jedoch eine Eigenschaft (RefreshTokenValidity) Ihres UserPoolClient, die Sie ändern können. Wenn Sie dies tun, wird in getSession () zuerst geprüft, ob die im Speicher befindlichen Token vorhanden sind und noch gültig sind. Andernfalls wird versucht, das dort gefundene refreshToken zu verwenden, um Sie für eine neue Sitzung zu authentifizieren.

Die Dokumentation http://docs.aws.Amazon.com/cognito/latest/developerguide/Amazon-cognito-user-pools-using-tokens-with-identity-providers.html gibt an, dass die iOS- und Android-SDKs Ich werde dies für Sie tun, obwohl ich sie nicht verwendet habe, also kann ich nicht dafür bürgen.

5
pisomojado

Ich habe auch in Javascript damit zu kämpfen. Hier ist meine Lösung, sie basiert auf https://github.com/aws/Amazon-cognito-identity-js , ABER sie ist nicht auf Speicher angewiesen, sodass Sie sie in einer Lambda-Funktion verwenden können, wenn Sie möchten. Bearbeiten: Festgelegter Code dank 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
})
4
GrumpyOldMan

Hier ein Beispiel, wie Sie dies auf der Serverseite mit JavaScript mithilfe von Node.js tun.

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

Ein vollständiges Arbeitsbeispiel finden Sie in meinem Blogbeitrag So authentifizieren Sie Benutzer mit Token mit Cognito .

3
Rick

Wenn Sie ein Aktualisierungstoken haben, können Sie neuen Zugriff, eine neue ID und ein Aktualisierungstoken erhalten, indem Sie einfach diese einfache POST - Anforderung an cognito senden:

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

Sie erhalten folgende Antwort zurück:

HTTP/1.1 200 OK
Content-Type: application/json

{
   "access_token":"eyJz9sdfsdfsdfsd", 
   "refresh_token":"dn43ud8uj32nk2je",
   "id_token":"dmcxd329ujdmkemkd349r",
   "token_type":"Bearer", 
   "expires_in":3600
}
0
Gautam Jain