web-dev-qa-db-ja.com

Cognitoユーザープール:更新トークンを使用してアクセストークンを更新する方法

Cognitoユーザープールを使用して、システム内のユーザーを認証しています。認証に成功すると、IDトークン(JWT)、アクセストークン(JWT)、および更新トークンが提供されます。ここのドキュメント http://docs.aws.Amazon.com/cognito/latest/developerguide/Amazon-cognito-user-pools-using-tokens-with-identity-providers.html 、明らかに更新トークンを使用してアクセストークンを更新できることについて言及していますが、その方法については言及していません。私の質問は、アクセストークンの有効期限が切れたら、保存された更新トークンを使用してアクセストークンを再度更新するにはどうすればよいですか?

JavaScript SDKを検索しましたが、同じことを行う方法が見つかりませんでした。私は間違いなく何かを見逃した。

また、アクセストークンと更新トークンを受け取り、更新されたアクセストークンで応答するLambda関数を介してこれを考えていました。誰かがこれに何らかの光を投げることができれば素晴らしいでしょう。

ありがとう

35
Hardik Shah

Cognito Javascript SDKが目的に合わせて機能しない場合でも、 SDKソース で更新プロセスの処理方法を確認できます。

refreshSessionで、Cognito InitiateAuth エンドポイントがAuthFlow値に設定されたREFRESH_TOKEN_AUTHで呼び出され、オブジェクトがAuthParameters値として渡されていることがわかります。

そのオブジェクトは、ユーザープールのニーズに合わせて構成する必要があります。具体的には、対象のアプリクライアントIDにアプリクライアントシークレットが関連付けられている場合は、SECRET_HASHを渡す必要があります。現在、Javascript SDKで使用するために作成されたユーザープールクライアントアプリにはクライアントシークレットを含めることができないため、それらに接続するためにSECRET_HASHは必要ありません。

ユーザープールがデバイスを記憶するように設定されており、DEVICE_KEYREFRESH_TOKENと一緒に渡さない場合、ループが発生する可能性がある別の注意事項があります。現在、RefreshTokenも渡さずにDeviceKeyを渡した場合、Cognito APIは "Invalid Refresh Token" エラーを返します。有効なRefreshTokenを渡した場合でも、このエラーが返されます。上記のリンクのスレッドはそれを照らしますが、AWSがエラー処理を更新して将来的にはよりわかりにくいものにしたいと思っています。

そのスレッドで説明したように、 AdminInitiateAuthADMIN_NO_SRP_AUTHとともに使用している場合、成功した認証応答ペイロードには現在NewDeviceMetadataが含まれていません。つまり、トークンを更新しようとするときに渡すDeviceKeyがありません。

私のアプリはPythonでの実装を要求しているので、ここで私のために働いた例があります:

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

Javascript sdkは、トークンの更新を内部的に処理します。 「getSession」を呼び出してトークンを取得すると、有効なキャッシュアクセスおよびIDトークンがない場合、SDKは更新トークンを使用して新しいアクセスおよびIDトークンを取得します。更新トークンも期限切れの場合にのみ、ユーザー認証を呼び出して、ユーザーにユーザー名とパスワードの入力を要求します。

よろしく、マヘシュ

19
M Reddy

Amazon-cognito-identity-jsブラウザーSDKでセッションを更新します。それはほとんどあなたのためにそれを行い、あなたが何か異常なことをしていない限り、リフレッシュトークンを直接処理する必要はありません。知っておくべきことは次のとおりです。

次のようにユーザープールをインスタンス化したと仮定します。

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

最後に認証されたユーザー名を見つけるには、次のようにします。

const cognitoUser = cognitoUserPool.getCurrentUser();

見つかった場合、cognitoUserはnull以外になります。これを行うと、必要に応じて舞台裏でトークンが更新されます。

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

これらのトークンをローカルストレージに保持したくない場合は、次のことができます。

cognitoUser.signOut();

それが機能する方法は、認証が成功した後、ブラウザがその更新トークンを含むJWTトークンを保存することです。これらはデフォルトでブラウザのローカルストレージに保存されますが、必要に応じて独自のストレージオブジェクトを提供できます。デフォルトでは、リフレッシュトークンは30日間有効ですが、UserPoolClientのプロパティ(RefreshTokenValidity)であり、変更できます。上記を実行すると、getSession()はまず、ストレージにあるトークンが存在し、まだ有効であるかどうかを確認します。そうでない場合は、そこで見つかったrefreshTokenを使用して、新しいセッションへの認証を試みます。

ドキュメント http://docs.aws.Amazon.com/cognito/latest/developerguide/Amazon-cognito-user-pools-using-tokens-with-identity-providers.html は、iOS and Android SDKはこれをあなたのために行いますが、私はそれらを使用していないので、それを保証することはできません。

7
pisomojado

Javascriptでもこれに苦労しています。ここに私のソリューションがあります、それは https://github.com/aws/Amazon-cognito-identity-js に基づいていますが、ストレージに依存していないので、ラムダ関数で使用できますあなたが望む。編集:クレヨンのおかげでコードを修正

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

Node.jsを使用してサーバー側でJavaScriptを使用して実行する方法の例を次に示します。

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

私のブログ投稿で完全な実例を見ることができます Cognitoを使用してトークンでユーザーを認証する方法

4
Rick

リフレッシュトークンがある場合は、次の単純なPOSTリクエストを認識してください)するだけで、新しいアクセス、ID、およびリフレッシュトークンを取得できます。

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

次の応答が返されます。

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

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