経緯
amazon-cognito-identity-js
を使いブラウザからAmazon Cognitoで認証してDynamoDBにアクセスできるところまでを確認。
その後ログアウトして、別のユーザーでログインしようとしたところ次のエラーが発生した。
Logins don't match. Please include at least one valid login for this identity or identity pool
原因
AWS認証情報取得が成功する時のシーケンスはこんな感じ。ユーザー認証(Login)あたりは簡略化している。
エラーが発生した際はLoginの後にGetIdを行わずにGetCredentialsForIdentityを行って400(Bad Request)が返ってくる。
ではなぜGetIdが省略されてしまったのか?
amazon-cognito-identity-js
を使うとCognitoUser
のsignOut()
を呼び出してもローカルストレージにはIdentityIdが残ったままである。そのため別ユーザーでLoginしてもIdentityIdが残っていると判断されてGetId
が省略されてしまう。
対処方法その1
AWS.CognitoIdentityCredentials
のコンストラクタの説明を見るとExamples
の中に次の記述がある。
// optional, only necessary when application runs in a browser
// and multiple users are signed in at once, used for caching
LoginId: 'example@gmail.com'
ブラウザで複数ユーザーがサインインする場合は必要だと書いている。。。
というわけで早速AWS.CognitoIdentityCredentials
の作成時にLoginId
を指定できるようにしてみる。
function createCognitoIdentityCredentials(session, loginId) {
var params = {
IdentityPoolId: 'ap-northeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
LoginId: (loginId) ? loginId : undefined,
Logins: {
'cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_xxxxxxxxx': session.getIdToken().getJwtToken();
},
};
return new AWS.CognitoIdentityCredentials(params);
}
実際に動かすとLoginId
の有無でIdentityIdをローカルストレージに保存する際のKeyが変化する。
LoginId | key |
---|---|
なし | aws.cognito.identity-id.<identity_pool_id> |
あり | aws.cognito.identity-id.<identity_pool_id><LoginId> |
IdentityIdを保存するKeyがユーザーごとにユニークになるため、ログインするユーザーが変わっても他人のIdentityIdを間違って使ってしまうことがなくなる。
例ではメールアドレスになっているけれど、ユーザーごとにユニークな値であれば問題ないと思われる。
対処方法その2
サインアウトしたのにローカルストレージにIdentityIdが残っているのが悪い!!!
ということで、CognitoIdentityCredentials
のclearCachedId()
をサインアウト時に呼び出すことでローカルストレージを綺麗にする。
function signOut() {
var cognitoUser = userPool.getCurrentUser();
if (cognitoUser != null) {
if (AWS.config.credentials && AWS.config.credentials.clearCachedId) {
AWS.config.credentials.clearCachedId();
}
cognitoUser.signOut();
}
}
その1、その2のどちらかを行えばよい。両方を行ってもよい。
ライブラリのバージョン
ライブラリのバージョンによって差があるかもしれないので覚え書き。
"amazon-cognito-identity-js": "^1.28.0",
"aws-sdk": "^2.171.0",