ユーザーを限定するwebサイト・webアプリはログインの仕組みが必要になる.
AWS cognito, 特にUser Poolsの機能でこれが実装できる.
Cognitoとは何ぞ?という方はこちら一読を推奨.
tarepan.hatenablog.com
Cognitoを用いたセッション管理の大枠
- インターネットを介した初回認証、認証情報のローカル (ブラウザ) への保存
- 各webページ/アプリ遷移でローカル認証情報のチェック、不正ならトップページ/ログイン画面へ強制リンク
初回認証時のデータがローカルへ自動保存され、必要に応じてページ遷移時などに読み出し関数でそれをチェック (validation)、未ログイン・期限切れ等の場合はそのページから追い出す.
AWS Cognito UserPoolsを利用すれば、関数を数個叩くだけでこの仕組みが実装できる, すごいぞ Amazon.
詳細
- JWT (Json Web Token)
- 認証フロー
の知識があると良い。
認証時にlocalStorageへJwtTokenをセットし、"その後"はgetSessionでtokenの取り出し・利用期限のvalidationする。不正な場合はgetSessionのcallback内でログインページへ飛ばす.
"その後"ではネットワークを介したチェックはしてなさそう.
ログアウト時にはlocalStorageとsession変数を空にしてる.
初回 : ネットワーク介した認証
2回目以降 : localStorageのtokensをvalidationして許可
ユーザー認証とページをまたいだログインの重要コード
UserPoolインスタンスの作成
new CognitoIdP.CognitoUserPool(data)
- @param {object} data / Creation options.
CognitoUser.authenticateUser
内部でauthRequest (CognitoIdPネイティブ関数) を叩き、所定の認証プロセスを通過したら
- signInUserSessionへのセット
- localStorageへのcache
を実行
// amazon-cognito-identity-js/src/CognitoUser.js // most important: line 225 - 227 export default class CognitoUser { ... authenticateUser(authDetails, callback) { ... this.client.makeUnauthenticatedRequest('initiateAuth', { ... }, (err, data) => { ... this.client.makeUnauthenticatedRequest('respondToAuthChallenge', { ...}, (errAuthenticate, dataAuthenticate) => { ... this.signInUserSession = this.getCognitoUserSession(dataAuthenticate.AuthenticationResult); this.cacheTokens(); ... }); }); }} // line 77 constructor(data){ ... this.client = data.Pool.client; } // amazon-cognito-identity-js/src/CognitoUserPool.js export default class CognitoUserPool { ... constructor(data) { ... this.client = new CognitoIdentityServiceProvider({ apiVersion: '2016-04-19', region }); }}
getCurrentUser
CognitoUserPool.getCurrentUser()
最後に認証したユーザー名をlocalStorageから取り出し、CognitoUserにして返す.いない場合はnull.
localStorageへの登録タイミングは CognitoUser.cacheToken() 実行時のみ.
実行タイミングは CognitoUser.authenticateUser() のみ.
()=>CognitoUser(LastAuthUser)
// amazon-cognito-identity-js/src/CognitoUser.js // important: line 788 - 800 export default class CognitoUser { ... cacheTokens() { const keyPrefix = `CognitoIdentityServiceProvider.${this.pool.getClientId()}`; ... const lastUserKey = `${keyPrefix}.LastAuthUser`; ... storage.setItem(lastUserKey, this.username); } ... }
getSession
validなtokensを検出した場合にcallbackが実行される.
cognitoUser.getSession(callback)
callback: (err, signInUserSession)=>{}
cognitoUserにvalidなsignInUserSessionがあれば即callback実行.
ない場合はユーザー名をもとにlocalStorageからtokenを取得、CognitoUserSessionに入れ、validならcallback実行.
期限切れ (invalid) ならrefreshTokenを用いて取得し直し、その後 callback.
他の場合はErrorでcallback実行.
CognitoUserSession
IdToken, AccessToken, RefreshTokenの入れ物. validation check関数 (isValid) を実装.
AWS Cognito Identityとの関係
ユーザー登録・ログイン・セッション管理は (基本的に) User Pools上で完結する.
Identity PoolやFederated Identityの仕組みは、他のAWS resourceへのアクセス等に必要になる.
amazon-cognito-identity-js
全ては解決した。amazon-cognito-identity-js は AWS.CognitoIdenitityServiceProviderをメソッド追加で拡張している。
参考
Integrating User Pools with Amazon Cognito Identity - Amazon Cognito