🥯

AWS Cognito認証、React編

2021/12/04に公開

概要:

Cognito認証、 react実装となります。


構成

  • aws Cognito
  • react 17

参考のコード

https://github.com/kuc-arc-f/react_ts3_cognito


関連

https://www.tdi.co.jp/miso/amazon-cognito-sign-up

https://qiita.com/y4u0t2a1r0/items/afe7a807604a1358492a


準備

  • congnite登録は やや複雑でしたので、上記関連を参考にしました。詳細は省略します

  • 登録手順の概要

  • ユーザープール 、登録

  • アプリクライント登録 (ユーザープル内)

  • IDプール登録


  • 補足

  • ユーザープール、サインイン方法は。eメール にしました

  • 標準属性は、今回は追加なし

  • ポリシー:「クライアントシークレットを生成」のチェックを外す

  • アプリクライアント, アプリクライアントID メモしておく

  • ユーザープール後、全体設定のプール ID メモしておく

  • IDプールの作成、IDプールのID(IdentityPoolId)メモしておく。


認証の実装

  • コードは、上記関連とほぼ同様になります。

  • 準備、

  • npm add

npm i --save amazon-cognito-identity-js
  • /src/awsConfiguration.ts

region: 設置したリージョン
IdentityPoolId: 上記の、IDプールのID
UserPoolId: 上記の、全体設定のプール ID
ClientId: 上記の、アプリクライアントID

awsConfiguration.ts
const awsConfiguration = {
  region: 'us-east-1',
  IdentityPoolId: '',
  UserPoolId: '',
  ClientId: '',
}


  • 登録:sign_up.tsx
sign_up.tsx
import React from 'react'
//import '../App.css'

import {
  CognitoUserPool,
  CognitoUserAttribute
} from "amazon-cognito-identity-js"
import awsConfiguration from '../../awsConfiguration'

const userPool = new CognitoUserPool({
  UserPoolId: awsConfiguration.UserPoolId,
  ClientId: awsConfiguration.ClientId,
})

//const SignUp: React.FC = () => {
export default function Page() {  
  const [email, setEmail] = React.useState<string>('')
  const [password, setPassword] = React.useState<string>('')

  const changedEmailHandler = (event: any) => setEmail(event.target.value)
  const changedPasswordHandler = (event: any) => setPassword(event.target.value)
  const signUp = () => {
    const attributeList = [
      new CognitoUserAttribute({
        Name: 'email',
        Value: email
      })
    ]
    userPool.signUp(email, password, attributeList, [], (err, result) => {
      if (err) {
        console.error(err)
        console.error(result)
        alert("Error, signUp");
        return
      }
      setEmail('')
      setPassword('');
      console.log("conmplete, SignUp !!");
    })
  }

  return (
    <div className="remix__page">
      <h1 style={{ textAlign: 'left' }}>SignUp</h1>
      <hr />
      <input type="text" placeholder="email" onChange={changedEmailHandler} /><br />
      <input type="text" placeholder="password" onChange={changedPasswordHandler} /><br />
      <button onClick={signUp}>SignUp</button>
    </div>
  )
}
//export default SignUp


  • 検証: verification.tsx
verification.tsx
import React from 'react'
//import '../App.css'

import {
  CognitoUserPool,
  CognitoUser
} from "amazon-cognito-identity-js"
import awsConfiguration from '../../awsConfiguration'

const userPool = new CognitoUserPool({
  UserPoolId: awsConfiguration.UserPoolId,
  ClientId: awsConfiguration.ClientId,
})

const Verification: React.FC = () => {
  const [email, setEmail] = React.useState<string>('')
  const [verificationCode, setVerificationCode] = React.useState<string>('')
  const changedEmailHandler = (event: any) => setEmail(event.target.value)
  const changedVerificationCodeHandler = (event: any) => setVerificationCode(event.target.value)

  const verifyCode = () => {
    const cognitoUser = new CognitoUser({
      Username: email,
      Pool: userPool
    })
    cognitoUser.confirmRegistration(verificationCode, true, (err: any) => {
      if (err) {
        console.log(err)
        return
      }
      console.log('verification succeeded')
      setEmail('')
      setVerificationCode('')
    })
  }
  return (
    <div className="Verification">
      <h1>Authenticate</h1>
      <input type="text" placeholder="verification code" onChange={changedVerificationCodeHandler} />
      <br />
      <input type="text" placeholder='email' onChange={changedEmailHandler} /><br />
      <button onClick={verifyCode}>Authenticate</button>
    </div>
  )
}

export default Verification
  • ログイン:sign_in.tsx
sign_in.tsx
import React from 'react'
//import '../App.css'

import {
  CognitoUserPool,
  CognitoUser,
  AuthenticationDetails
} from "amazon-cognito-identity-js"
import awsConfiguration from '../../awsConfiguration'

const userPool = new CognitoUserPool({
  UserPoolId: awsConfiguration.UserPoolId,
  ClientId: awsConfiguration.ClientId,
})

const SignIn: React.FC = () => {
  const [email, setEmail] = React.useState<string>('')
  const [password, setPassword] = React.useState<string>('')
  const changedEmailHaldler = (e: any) => setEmail(e.target.value)
  const changedPasswordHandler = (e: any) => setPassword(e.target.value)

  const signIn = () => {
    const authenticationDetails = new AuthenticationDetails({
      Username : email,
      Password : password
    })
    const cognitoUser = new CognitoUser({
      Username: email,
      Pool: userPool
    })

    cognitoUser.authenticateUser(authenticationDetails, {
      onSuccess: (result) => {
        console.log('result: ' + result)
        const accessToken = result.getAccessToken().getJwtToken()
        console.log('AccessToken: ' + accessToken)
        setEmail('')
        setPassword('')
        console.log("OK, signIn");
      },
      onFailure: (err) => {
        alert('NG, Login please check email, password');
        console.log("NG, signIn:onFailure");
        console.error(err)
      }
    })
  }

  const checkLogin = () => {
    const cognitoUser = userPool.getCurrentUser()
    if (cognitoUser) {
      console.log('OK, sign in')
    } else {
      console.log('not, signing in')
    }
  }

  return (
    <div className="SignIn">
      <h1>SingIn</h1>
      <input type="text" placeholder='email' onChange={changedEmailHaldler}/><br />
      <input type="text" placeholder='password' onChange={changedPasswordHandler}/><br />
      <button onClick={signIn}>Sign In</button>
      <br />
      <button onClick={checkLogin}>checkLogin</button>

    </div>
  )
}

export default SignIn
  • ログアウト:sign_out:
    /src/component/auth/sign_out.tsx

  • 補足

  • sign_upすると、検証コードが メール送信されて。

  • verificationで、検証コード、メールを登録すると、アカウントがメール確認済の状態に変更される

  • sign_inすると、ログイン状態になり。
    ローカルストレージに保存されている。ユーザー状態を確認可能になる


  • package.json
{
  "name": "react_ts",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "@types/jest": "^26.0.15",
    "@types/node": "^12.0.0",
    "@types/react": "^17.0.0",
    "@types/react-dom": "^17.0.0",
    "@types/react-router-dom": "^5.3.0",
    "amazon-cognito-identity-js": "^5.2.3",
    "moment": "^2.29.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "^5.3.0",
    "react-scripts": "4.0.3",
    "typescript": "^4.1.2",
    "web-vitals": "^1.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}


....

Discussion