こういう人向けの記事
- Amazon Cognitoを使いたい
- Webサイトにログイン機能を実装したい
- ES2015(ES6)で書きたい
- WebpackとかBabelとか使いたい
- ReactとかAngularとか使いたい
Cognitoの素晴らしい点
- 機能がめちゃくちゃ充実(ユーザー認証まわりの機能ほぼ揃ってる)
- 開発コスト大幅削減(自分で作ろうとしたら数週間〜数ヶ月かかる)
- 運用コストゼロ(自動スケール、障害対応不要)
- 他社より安い(5万MAUまで無料、以降も比較的安い)
- AWSコンソール上でユーザー情報一覧を閲覧できる
- 何もしなくても日々進化してくれる
Cognitoの残念な点
- CognitoのJavaScript対応はまだまだ発展途上
- 不条理な仕様、ハマりどころが多々あることを覚悟する
- ES6、Promise等々を使うなら公式READMEに書かれてるコードはそのまま使えないので注意
日々進化してるのでそのうち解消されるはず
事前準備
以下作業が必要。他のQiitaやブログで紹介されているので割愛。
- AWS CLIをインストール
- AWSコンソールでCognitoのアイデンティティプール(認証情報が保存されるDB的な)を作成
- AWSコンソールでCognitoのユーザープール(ユーザー情報が保存されるDB的な)を作成
- そのユーザープールにアプリクライアントを追加(※注:Webブラウザで使用する場合には
クライアントシークレットを生成する
のチェックを外す)
AWS CLIでユーザーを作る
Web画面上でユーザーを作ると別途JS側からパスワード再設定しなければならないので、CLIで作る。
aws cognito-idp sign-up --client-id <アプリクライアントID> --username <ユーザー名(メアド認証の場合はメアド)> --password <パスワード> --user-attributes Name=email,Value=<メアド>
aws cognito-idp admin-confirm-sign-up --user-pool-id <ユーザープールID> --username <ユーザー名(メアド認証の場合はメアド)>
必要なパッケージをインストール
AWS SDKとAWS Cognito SDKはともに amazon-cognito-identity-js
をnpm installするだけで内包される。
amazon-cognito-identity-js
はAWS公式JavaScriptライブラリ。
Promise.promisify()
を使わない方は bluebird
は入れなくてもOK。
npm i -S bluebird
npm i -S amazon-cognito-identity-js
npm i -D webpack json-loader
ログイン機能を実装
以下コードはサーバーサイドではなくフロントエンドです。
View(HTML/CSS)のコードは割愛しますが、ReactでもAngularでも何でもOK。
UserUtil.js
import Promise from 'bluebird'
import AWS from 'aws-sdk'
import {
CognitoUserPool,
CognitoUserAttribute,
CognitoUser,
AuthenticationDetails,
} from 'amazon-cognito-identity-js'
const REGION = '<リージョン>'
const IDENTITY_POOL_ID = '<アイデンティティプールID>'
const USER_POOL_ID = '<ユーザープールID>'
const APP_CLIENT_ID = '<アプリクライアントID>'
const userPool = new CognitoUserPool({
UserPoolId: USER_POOL_ID,
ClientId: APP_CLIENT_ID,
})
export function signIn(Username, Password) {
const authenticationDetails = new AuthenticationDetails({Username, Password})
const cognitoUser = new CognitoUser({
Username,
Pool: userPool
})
return new Promise((resolve, reject)=>{
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: (result)=>{
resolve(getAccessToken(result))
},
onFailure: (err)=>{
reject(err)
},
newPasswordRequired: ()=>{
reject('Change your password')
}
})
})
}
export function getSession() {
const cognitoUser = userPool.getCurrentUser()
if ( !cognitoUser ) return Promise.reject('Current user not found')
return Promise.promisify(::cognitoUser.getSession)()
.then((result)=>{
if ( !result ) return Promise.reject('Session not found')
return getAccessToken(result)
})
}
export function getAccessToken(result) {
return result.getAccessToken().getJwtToken()
}
index.js
import * as UserUtil from './UserUtil'
// ログイン
export function signIn() {
const Username = '<ブラウザで入力されたユーザー名>'
const Password = '<ブラウザで入力されたパスワード>'
UserUtil
.signIn(Username, Password)
.then((accessToken)=>{
// ログイン成功時の処理
})
.catch((err)=>{
// ログイン失敗時の処理
})
}
// ログイン後のセッション取得
export function getSession() {
UserUtil
.getSession()
.then((accessToken)=>{
// セッション取得成功時の処理
})
.catch((err)=>{
// セッション取得失敗時の処理
})
}
参考にさせていただいたページ
http://qiita.com/Yuki_BB3/items/ee8330830951acd907de
https://github.com/aws/amazon-cognito-identity-js