はじめに
皆さん。こんにちは!
DreamHanksのエルムです。
今回はパスワード & ユーザー管理について説明していきます。
前回の記事はMulti-factor 認証 (Multi-factor authentication)です。
パスワード操作について (Password operations)
パスワードの変更
1 2 3 4 5 6 7 8 |
import { Auth } from 'aws-amplify'; Auth.currentAuthenticatedUser() .then(user => { return Auth.changePassword(user, 'oldPassword', 'newPassword'); }) .then(data => console.log(data)) .catch(err => console.log(err)); |
パスワードを忘れた場合 (Forgot password)
1 2 3 4 5 6 7 8 9 10 11 |
import { Auth } from 'aws-amplify'; // ユーザーのメールに確認コードを送信 Auth.forgotPassword(username) .then(data => console.log(data)) .catch(err => console.log(err)); // 確認コードと新しいパスワードの入力 Auth.forgotPasswordSubmit(username, code, new_password) .then(data => console.log(data)) .catch(err => console.log(err)); |
新しいパスワードの入力 (Complete new password)
有効なユーザーディレクトリがAmazon Cognitoで作成されている場合、ユーザーは最初のサインイン試行時に新しいパスワードと必要な属性の提供を求められます。このシナリオでは、次のメソッドを呼び出して、ユーザーが入力した新しいパスワードを処理することができます。
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 |
import { Auth } from 'aws-amplify'; Auth.signIn(username, password) .then(user => { if (user.challengeName === 'NEW_PASSWORD_REQUIRED') { const { requiredAttributes } = user.challengeParam; // 必要な属性の配列、例:['email', 'phone_number'] Auth.completeNewPassword( user, // Cognitoユーザーオブジェクト newPassword, // 新しいパスワード // オプション、必要な属性 { email: 'xxxx@dreamhanks.com', phone_number: '1234567890' } ).then(user => { // MFAが必要ない場合、この時点でユーザーはログインしています。 console.log(user); }).catch(e => { console.log(e); }); } else { // その他の状況 } }).catch(e => { console.log(e); }); |
アカウント回復の検証 (Account recovery verification)
アカウントの復旧には、電話番号かメールアドレスのどちらかが必要です。
ユーザーにそれらの属性を確認させることができます:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// phone_number」や「email」などの属性を検証するプロセスを開始するには Auth.verifyCurrentUserAttribute(attr) .then(() => { console.log('認証コードが送信されました'); }).catch((e) => { console.log('エラーで失敗', e); }); // コードで属性を確認する場合 Auth.verifyCurrentUserAttributeSubmit(attr, 'the_verification_code') .then(() => { console.log('phone_numberの検証'); }).catch(e => { console.log('エラーで失敗', e); }); |
現在認証されているユーザーを取得する方法
Auth.currentAuthenticatedUser()を呼べば、現在の認証済みユーザーオブジェクトを取得できます。
1 2 3 4 5 6 |
import { Auth } from 'aws-amplify'; Auth.currentAuthenticatedUser({ bypassCache: false // オプション、デフォルトではfalseです。trueに設定すると、このコールはCognitoにリクエストを送信し、最新のユーザーデータを取得します。 }).then(user => console.log(user)) .catch(err => console.log(err)); |
このメソッドは、ページが読み込まれたときに、ユーザーがログインしているかどうかを確認するために使用できます。ログインしているユーザーがいない場合は、エラーが発生します。
このメソッドは、Authモジュールが設定された後、またはユーザーがログインした後に呼び出される必要があります。 Authイベントの “configured ” や “signIn “を確実に聞き取ることができるようにする。
現在認証されているユーザーの属性を取得する方法
また、Auth.currentAuthenticatedUserが返すユーザーオブジェクトから、メールアドレスや電話番号、サブなど、ユーザーに関連する属性にアクセスすることもできます。
1 |
const { attributes } = await Auth.currentAuthenticatedUser(); |
現在のセッションを取得する方法
Auth.currentSession()は、JWT accessToken, idToken, refreshTokenを含むCognitoUserSessionオブジェクトを返します。
このメソッドは、トークンの有効期限が切れ、有効なrefreshTokenが提示されると、accessTokenとidTokenを自動的に更新します。
そのため、必要に応じてこのメソッドを使ってセッションを更新することができます:
1 2 3 4 5 |
import { Auth } from 'aws-amplify'; Auth.currentSession() .then(data => console.log(data)) .catch(err => console.log(err)); |
ユーザー属性の管理 (Managing user attributes)
サインアップ時にユーザーの属性を渡すことができます:
1 2 3 4 5 6 7 8 9 10 11 |
Auth.signUp({ 'username': 'elmu', 'password': 'mysecurerandompassword#123', 'attributes': { 'email': 'me@dreamhanks.com', 'phone_number': '82105601234', 'given_name': 'Elmurodjon', 'family_name': 'Tadjibaev', 'nickname': 'Elmu' } }); |
ユーザーの属性を取得することができます:
1 2 3 |
let user = await Auth.currentAuthenticatedUser(); const { attributes } = user; |
ユーザーの属性を更新することができます:
1 2 3 4 5 6 7 |
let user = await Auth.currentAuthenticatedUser(); let result = await Auth.updateUserAttributes(user, { 'email': 'me@gmail.com', 'family_name': 'Lastname' }); console.log(result); // サクセス |
メールアドレスを変更した場合、ユーザーは確認コードを受け取ります。アプリでは、確認コードを確認することができます。
1 |
let result = await Auth.verifyCurrentUserAttributeSubmit('email', 'abc123'); |
セキュリティートークンの管理する方法 (Managing security tokens)
AWS AmplifyでAuthenticationを使用する場合、Amazon Cognitoのトークンを手動でリフレッシュする必要はありません。トークンは必要に応じてライブラリによって自動的に更新されます。
IdTokenやAccessTokenなどのSecurity Tokensは、ブラウザではlocalStorageに、React NativeではAsyncStorageに格納されます。トークンをより安全な場所に保管したい場合や、Amplifyをサーバーサイドで使用している場合は、独自のストレージ・オブジェクトを提供してトークンを保管することができます。
例えば、以下のように:
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 |
class MyStorage { // シンク関数から返されるプロミス static syncPromise = null; // キーのセットアイテム static setItem(key: string, value: string): string; // キーを持つアイテムの取得 static getItem(key: string): string; // キーでアイテムを削除 static removeItem(key: string): void; // ストレージを片付ける static clear(): void; // ストレージ操作が非同期の場合(AsyncStorage) // そして、それらのアイテムを以下の方法でメモリに同期させる必要があります。 static sync(): Promise<void> { if (!MyStorage.syncPromise) { MyStorage.syncPromise = new Promise((res, rej) => {}); } return MyStorage.syncPromise; } } // Authにストレージオブジェクトを使用するように伝えます。 Auth.configure({ storage: MyStorage }); |
以下のように: AsyncStorageをストレージオブジェクトとして使用する例として、AsyncStorageからMemoryにアイテムを同期させる方法を紹介します。
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 58 59 60 61 62 63 64 65 66 67 68 69 |
import { AsyncStorage } from 'react-native'; const MYSTORAGE_KEY_PREFIX = '@MyStorage:'; let dataMemory = {}; /** @class */ class MyStorage { static syncPromise = null; /** * 特定のアイテムをストレージにセットする際に使用します。 */ static setItem(key, value) { AsyncStorage.setItem(MYSTORAGE_KEY_PREFIX + key, value); dataMemory[key] = value; return dataMemory[key]; } /** * これは、ストレージから特定のキーを取得するために使用されます。 */ static getItem(key) { return Object.prototype.hasOwnProperty.call(dataMemory, key) ? dataMemory[key] : undefined; } /** * ストレージからアイテムを取り出す際に使用します。 */ static removeItem(key) { AsyncStorage.removeItem(MYSTORAGE_KEY_PREFIX + key); return delete dataMemory[key]; } /** * これは、ストレージをクリアするために */ static clear() { dataMemory = {}; return dataMemory; } /** * MyStorageのデータをAsyncStorageからstorageWindowのMyStorageに同期します。 */ static sync() { if (!MyStorage.syncPromise) { MyStorage.syncPromise = new Promise((res, rej) => { AsyncStorage.getAllKeys((errKeys, keys) => { if (errKeys) rej(errKeys); const memoryKeys = keys.filter((key) => key.startsWith(MYSTORAGE_KEY_PREFIX)); AsyncStorage.multiGet(memoryKeys, (err, stores) => { if (err) rej(err); stores.map((result, index, store) => { const key = store[index][0]; const value = store[index][1]; const memoryKey = key.replace(MYSTORAGE_KEY_PREFIX, ''); dataMemory[memoryKey] = value; }); res(); }); }); }); } return MyStorage.syncPromise; } } Auth.configure({ storage: MyStorage }); |
トークンの詳細については、Amazon Cognito Developer Documentationをご覧ください。
終わりに
今回の記事は以上になります。
次回は[第9回] Userプール認証フローを学びましょう。
ご覧いただきありがとうございます。
コメント