AWSのCognitoでは、認証処理が成功するとトークンが払い出されます。
このトークンは3種類あり、IDトークンは更新トークンにより更新されたりするのですが、そこら辺の細かい話を今回はさらっと解説したいと思います。
Cognitoのトークンの種類
Cognitoのトークンは3種類あります。
・IDトークン
・アクセストークン
・更新トークン
IDトークンの有効期限は「1時間」ですが、更新トークンによってIDトークンは再取得されるため、更新トークンが切れない限り、IDトークンは切れないということになります。
Cognitoの更新トークンはマネージメントコンソールから設定を変更できます。デフォルトは「30日」です。
更新トークンを用いたIDトークン再取得処理
今回は、AngularでCognitoを使っているのもありJavaScriptの解説になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
/** * This is used to get a session, either from the session object * or from the local storage, or by using a refresh token * * @param {nodeCallback<CognitoUserSession>} callback Called on success or error. * @returns {void} */ getSession(callback) { if (this.username == null) { return callback(new Error('Username is null. Cannot retrieve a new session'), null); } if (this.signInUserSession != null && this.signInUserSession.isValid()) { return callback(null, this.signInUserSession); } const keyPrefix = `CognitoIdentityServiceProvider.${this.pool.getClientId()}.${this.username}`; const idTokenKey = `${keyPrefix}.idToken`; const accessTokenKey = `${keyPrefix}.accessToken`; const refreshTokenKey = `${keyPrefix}.refreshToken`; const clockDriftKey = `${keyPrefix}.clockDrift`; if (this.storage.getItem(idTokenKey)) { const idToken = new CognitoIdToken({ IdToken: this.storage.getItem(idTokenKey), }); const accessToken = new CognitoAccessToken({ AccessToken: this.storage.getItem(accessTokenKey), }); const refreshToken = new CognitoRefreshToken({ RefreshToken: this.storage.getItem(refreshTokenKey), }); const clockDrift = parseInt(this.storage.getItem(clockDriftKey), 0) || 0; const sessionData = { IdToken: idToken, AccessToken: accessToken, RefreshToken: refreshToken, ClockDrift: clockDrift, }; const cachedSession = new CognitoUserSession(sessionData); if (cachedSession.isValid()) { this.signInUserSession = cachedSession; return callback(null, this.signInUserSession); } if (!refreshToken.getToken()) { return callback(new Error('Cannot retrieve a new session. Please authenticate.'), null); } this.refreshSession(refreshToken, callback); } else { callback(new Error('Local storage is missing an ID Token, Please authenticate'), null); } return undefined; } |
ライブラリの「CognitoUser.js」というファイルに「refreshSession」という関数を呼び出している箇所があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
/** * This uses the refreshToken to retrieve a new session * @param {CognitoRefreshToken} refreshToken A previous session's refresh token. * @param {nodeCallback<CognitoUserSession>} callback Called on success or error. * @returns {void} */ refreshSession(refreshToken, callback) { const authParameters = {}; authParameters.REFRESH_TOKEN = refreshToken.getToken(); const keyPrefix = `CognitoIdentityServiceProvider.${this.pool.getClientId()}`; const lastUserKey = `${keyPrefix}.LastAuthUser`; if (this.storage.getItem(lastUserKey)) { this.username = this.storage.getItem(lastUserKey); const deviceKeyKey = `${keyPrefix}.${this.username}.deviceKey`; this.deviceKey = this.storage.getItem(deviceKeyKey); authParameters.DEVICE_KEY = this.deviceKey; } const jsonReq = { ClientId: this.pool.getClientId(), AuthFlow: 'REFRESH_TOKEN_AUTH', AuthParameters: authParameters, }; if (this.getUserContextData()) { jsonReq.UserContextData = this.getUserContextData(); } this.client.request('InitiateAuth', jsonReq, (err, authResult) => { if (err) { if (err.code === 'NotAuthorizedException') { this.clearCachedUser(); } return callback(err, null); } if (authResult) { const authenticationResult = authResult.AuthenticationResult; if (!Object.prototype.hasOwnProperty.call(authenticationResult, 'RefreshToken')) { authenticationResult.RefreshToken = refreshToken.getToken(); } this.signInUserSession = this.getCognitoUserSession(authenticationResult); this.cacheTokens(); return callback(null, this.signInUserSession); } return undefined; }); } |
「refreshSession」の内容です。
ここで、「更新トークンを用いたIDトークン再取得処理」を行っていると思われます。
まとめ
さすがにライブラリの中を追っていくのは骨が折れるのと、正直良く分からない部分も多いです。
が、なんとなく何をやっているのかは分かるので、ソースコードを見ていると勉強になるのは確かです。
ということで、さいなら!