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関数を介してこれを考えていました。誰かがこれに何らかの光を投げることができれば素晴らしいでしょう。
ありがとう
Cognito Javascript SDKが目的に合わせて機能しない場合でも、 SDKソース で更新プロセスの処理方法を確認できます。
refreshSession
で、Cognito InitiateAuth エンドポイントがAuthFlow
値に設定されたREFRESH_TOKEN_AUTH
で呼び出され、オブジェクトがAuthParameters
値として渡されていることがわかります。
そのオブジェクトは、ユーザープールのニーズに合わせて構成する必要があります。具体的には、対象のアプリクライアントIDにアプリクライアントシークレットが関連付けられている場合は、SECRET_HASH
を渡す必要があります。現在、Javascript SDKで使用するために作成されたユーザープールクライアントアプリにはクライアントシークレットを含めることができないため、それらに接続するためにSECRET_HASH
は必要ありません。
ユーザープールがデバイスを記憶するように設定されており、DEVICE_KEY
をREFRESH_TOKEN
と一緒に渡さない場合、ループが発生する可能性がある別の注意事項があります。現在、RefreshToken
も渡さずにDeviceKey
を渡した場合、Cognito APIは "Invalid Refresh Token" エラーを返します。有効なRefreshToken
を渡した場合でも、このエラーが返されます。上記のリンクのスレッドはそれを照らしますが、AWSがエラー処理を更新して将来的にはよりわかりにくいものにしたいと思っています。
そのスレッドで説明したように、 AdminInitiateAuth をADMIN_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
Javascript sdkは、トークンの更新を内部的に処理します。 「getSession」を呼び出してトークンを取得すると、有効なキャッシュアクセスおよびIDトークンがない場合、SDKは更新トークンを使用して新しいアクセスおよびIDトークンを取得します。更新トークンも期限切れの場合にのみ、ユーザー認証を呼び出して、ユーザーにユーザー名とパスワードの入力を要求します。
よろしく、マヘシュ
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はこれをあなたのために行いますが、私はそれらを使用していないので、それを保証することはできません。
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
})
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を使用してトークンでユーザーを認証する方法 。
リフレッシュトークンがある場合は、次の単純な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
}