LoginSignup
27
29

More than 5 years have passed since last update.

CognitoのWebサイトログインをES6で書く

Last updated at Posted at 2017-08-24

こういう人向けの記事

  • 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

27
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
29