LoginSignup
11
8

More than 5 years have passed since last update.

aws-amplify-react で sign up 時の電話番号を無効にする

Last updated at Posted at 2018-07-29

TL;DR

  • aws-amplify-react の Auth モジュールが提供する <SignUp> は電話番号が必須になっている。
  • これを無効にするには自分で専用の <CustomSignUp> を作る必要がある。

背景: 電話番号を無効にしたい

awsmobile-cli を使って作った AWS Mobile Hub プロジェクトに AWS Cognito を使った認証機能を追加することにしました。 CLI から User Pool を作って、 aws-amplify-react の withAuthenticator HOC を使ってみたところ、アカウント登録画面で電話番号が必須になっていました:

image.png

電話番号を省略しようとしてもバリデーションエラーが発生します:

image.png

awsmobile-cli から作った User Pool の設定を見るとたしかに「必須の属性」に「電話番号」があるので、改めて今度は「必須の属性」を「なし」で User Pool を作り直し、設定ファイル(aws-exports.js)を更新しましたが、依然としてフォームに電話番号の欄があり、必須のままでした。どうすれば電話番号の入力を無効にできるのでしょう?

aws-amplify-react はそこまで賢くない

aws-amplify は awsmobile-cli が生成する aws-exports.js という設定ファイルをそのまま読むことができます:

import Amplify from "aws-amplify"

// User Pool ID とかそういう情報が入っている。awsmobile-cli で自動生成される
import awsmobile from "./aws-exports"

Amplify.configure(awsmobile)

しかし、この aws-exports.js の中身をよくよく読んでみると、 User Pool ID などは書かれていますが、どういうものが必須かとかそういう情報は入っていません。

さらに悪いことに aws-amplify-react は awsmobile-cli でデフォルトで作られる User Pool に対応するようになっていて、登録時の項目を変更したかった場合は、自分でコードをたくさん書く必要があります。

カスタマイズする

ドキュメントによると withAuthenticator は内部的に <Autheticator> を使っており、こいつはさらに内部的に <SignIn> などを使っていて、特定のビューを変更するにはそのコンポーネントを拡張したコンポーネントを渡せば良いようです。今回の場合は <SignUp> を変更すれば良さそうです。残念ながら細かい部分はドキュメントが無いのでソースコードを見て空気を読んでやっていきます。

空気を読んで書いたコード

もとのファイルとの差分が分かりやすいように、削除したところをコメントアウトとして表現した。
SignUpWithoutPhoneNumber.jsx
import { Auth, I18n } from "aws-amplify"
import {
  ButtonRow,
  FormSection,
  InputRow,
  Link,
  SectionBody,
  SectionFooter,
  SectionHeader,
  SignUp,
} from "aws-amplify-react"
import * as React from "react"

export default class SignUpWithoutPhoneNumber extends SignUp {
  showComponent(theme) {
    const { hide } = this.props
    if (hide && hide.includes(SignUp)) {
      return null
    }

    return (
      <FormSection theme={theme}>
        <SectionHeader theme={theme}>{I18n.get("Sign Up Account")}</SectionHeader>
        <SectionBody theme={theme}>
          <InputRow
            autoFocus={true}
            placeholder={I18n.get("Username")}
            theme={theme}
            key="username"
            name="username"
            onChange={this.handleInputChange}
          />
          <InputRow
            placeholder={I18n.get("Password")}
            theme={theme}
            type="password"
            key="password"
            name="password"
            onChange={this.handleInputChange}
          />
          <InputRow
            placeholder={I18n.get("Email")}
            theme={theme}
            key="email"
            name="email"
            onChange={this.handleInputChange}
          />
          {/*<InputRow
            placeholder={I18n.get('Phone Number')}
            theme={theme}
            key="phone_number"
            name="phone_number"
            onChange={this.handleInputChange}
          />*/}
          <ButtonRow onClick={this.signUp} theme={theme}>
            {I18n.get("Sign Up")}
          </ButtonRow>
        </SectionBody>
        <SectionFooter theme={theme}>
          <div style={theme.col6}>
            <Link theme={theme} onClick={() => this.changeState("confirmSignUp")}>
              {I18n.get("Confirm a Code")}
            </Link>
          </div>
          <div style={Object.assign({ textAlign: "right" }, theme.col6)}>
            <Link theme={theme} onClick={() => this.changeState("signIn")}>
              {I18n.get("Sign In")}
            </Link>
          </div>
        </SectionFooter>
      </FormSection>
    )
  }

  async signUp() {
    const { username, password, email /*, phone_number */ } = this.inputs
    try {
      await Auth.signUp({
        attributes: {
          email,
          // phone_number,
        },
        password,
        username,
      })
      this.changeState("confirmSignUp", username)
    } catch (err) {
      this.error(err)
    }
  }
}


こうしてできた <SignUpWithoutPhoneNumber>withAuthenticator の第三引数に渡します:

App.jsx
import {
  ConfirmSignIn,
  ConfirmSignUp,
  ForgotPassword,
  SignIn,
  VerifyContact,
  withAuthenticator,
} from "aws-amplify-react"
import * as React from "react"

import SignUpWithoutPhoneNumber from "./SignUpWithoutPhoneNumber"

class App extends React.Component {
  // ...
}

export default withAuthenticator(App, false, [
  <SignIn />,
  <ConfirmSignIn />,
  <VerifyContact />,
  <SignUpWithoutPhoneNumber />, // ここ
  <ConfirmSignUp />,
  <ForgotPassword />,
])

これで無事に電話番号無しでアカウント作成できるようになった。

image.png

11
8
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
11
8