KurocoとNuxt.jsで、会員登録画面に仮登録機能を実装する

概要

新規会員登録時、登録メールアドレスあてに認証用のメールを送付し、リンクをクリックしたら登録される仮登録機能を実装します。

学べること

仮登録機能は以下の手順で実装します。

前提条件

このページは、KurocoとNuxt.jsでのプロジェクトが構築済みであることを前提としています。
まだ構築していない場合は、下記のチュートリアルを参照してください。
Kurocoビギナーズガイド
KurocoとNuxt.jsで、新規会員登録画面を構築する

APIの設定

まずは仮登録機能で使用するAPIを登録します。

API基本設定を行う

まずはAPIの登録をします。
Kurocoの管理画面から[API]->[Default]をクリックします。
Image from Gyazo

[追加]をクリックします。
Image from Gyazo

タイトル、版、ディスクリプションを入力して[追加する]をクリックします。
Image from Gyazo

追加したAPIに遷移しますので、続いて、セキュリティの設定をします。
[セキュリティ]をクリックします。
Image from Gyazo

[Cookie]を選択して[保存する]をクリックします。
fetched from Gyazo

注意)

  • セキュリティについては何らかの設定を適用してください。本チュートリアルでは、Cookieを利用します。
  • Cookieをセキュリティ用のトークンとして利用する場合、APIドメインとフロントエンドのドメインが違うとサードパティクッキーの問題があり、Safari等で認証が効きません。
    フロントエンドとAPIドメインをサブドメイン違いで設定をする必要があるので、独自ドメイン/TLS証明書でAPIドメインを設定し、アカウント設定からAPIドメインを変更ください。
    (Chromeでは正常に動作しますので、開発やテストの段階ではまずChromeで構築していただくことをお勧めします。)

CORS設定を行う

[CORSを設定する] をクリックします。

Image from Gyazo

CORS_ALLOW_ORIGINSの [Add Origin] をクリックし、下記を追加します。

  • http://localhost:3000/
  • フロントエンドドメイン
  • 管理画面URL

CORS_ALLOW_METHODSの [Add Method] をクリックし、下記を追加します。

  • GET
  • POST
  • OPTIONS

CORS_ALLOW_REDENTIALSの[Allow Credentials]にチェックが入っていることを確認します。

Image from Gyazo

問題なければ [保存する] をクリックします。

エンドポイントを設定する

次にエンドポイントを作成します。今回は下記エンドポイントを作成します。

  • メンバー登録のエンドポイント
  • 仮メンバー登録のエンドポイント

メンバー登録のエンドポイント

メンバー登録のエンドポイントを下記設定にて作成します。

項目設定内容
パスmember/regist
カテゴリーメンバー
モデルMember
オペレーションinsert
default_group_id適用するメンバーグループのIDを入力してください。
グループIDはグループより確認できます。
login_ok_flgチェックを入れる

Image from Gyazo Image from Gyazo

設定完了後、「追加する」をクリックします。

仮メンバー登録のエンドポイント

仮メンバー登録のエンドポイントを下記設定にて作成します。

項目設定内容
パスmember/invite
カテゴリーメンバー
モデルMember
オペレーションinvite

Image from Gyazo Image from Gyazo

設定完了後、「追加する」をクリックします。

Swagger UIで仮登録機能の動作を確認する

APIの設定ができたらまずはSwagger UIで動作の確認をします。

Member::inviteのエンドポイントで招待メールを送る

[Swagger UI]をクリックします。
Image from Gyazo

[/rcms-api/13/member/invite]をクリックします。
Image from Gyazo

[Try it out]をクリックします。
Image from Gyazo

Request bodyに以下のJSONデータを入力して[Execute]をクリックします。

{
  "email": "your_mail_address@example.com",
  "ext_info": {
    "name1": "Diverta",
    "name2": "Taro",
    "login_pwd": "PASSWORD"
  }
}

Image from Gyazo

200のレスポンスと、メールの受信を確認します。
Image from Gyazo

Image from Gyazo

メールの本文は後ほど修正するので、今はデフォルトのままで問題ありません。
URL末尾のkeyの部分が必要になるのでメモしておきます。

keyを利用して、仮メンバーの情報を取得する

先ほどメンバー情報をpostしたMember::inviteのエンドポイントに、今度は発行されたkey情報をpostします。

Member::inviteのRequest bodyに以下のJSONデータを入力して[Execute]をクリックします。

{
  "email_hash": "c0d4e2f342837dea935435803e82cdbc"
}

Image from Gyazo

email_hashの値はご自身のサイトで発行したkeyを利用してください。

すると、仮登録状態のメンバー情報がレスポンスされます。
Image from Gyazo

こちらの情報を利用して会員登録をします。

Member::insertのエンドポイントで会員登録をする

最後に、取得した仮メンバーの情報で会員登録のエンドポイントにリクエストして完了です。

Swagger UIで[/rcms-api/13/member/regist]をクリックします。
Image from Gyazo

[Try it out]をクリックします。
Image from Gyazo

Request bodyに以下のJSONデータを入力して[Execute]をクリックします。

{
  "email": "your_mail_address@example.com",
  "name1": "Diverta",
  "name2": "Taro",
  "login_pwd": "PASSWORD"
}

Image from Gyazo

メンバーの新規追加ができました。
Image from Gyazo

以上が仮登録機能の動作の流れになります。
この一覧の流れをフロントエンドで実装します。

メッセージひな形を調整する

フロントエンドの実装の前に、Member::inviteのエンドポイントを叩いた際に送付されるメールの内容を調整しておきます。

[オペレーション]->[メッセージひな形]をクリックします。
Image from Gyazo

識別子がmember/pre_regist_thanksのテンプレートを探して、テンプレート名をクリックします。
Image from Gyazo

メッセージひな形編集画面が開くので、以下のように修正して、[更新する]をクリックします。

RCMS-X-SUBJECT:{$smarty.const.SITE_TITLE}登録のご案内
{$ext_info.name1} {$ext_info.name2}様

弊社サイト{$smarty.const.SITE_TITLE} にご登録いただきありがとうございます。

以下のURLをクリックして登録を完了してください。  

■本登録用ページ
{$smarty.const.ROOT_URL}/login/signup_pre_regist/done/{$preregist_key}/

よろしくお願い申し上げます。

Image from Gyazo

フロントエンドの実装をする

最後に、以上の動作をするフロントエンドを作成します。

仮登録用のページ作成

/login/signup_pre_regist/のディレクトリにindex.vue のファイルを作成します。

/login/signup_pre_regist/index.vue
<template>
    <div>
        <div v-if="!presignupDone">
            <form @submit.prevent="signup">
                <p v-if="error" :style="{ color: 'red' }">
                    {{ error }}
                </p>

                <div>
                    <label>name1</label>
                    <input v-model="user.name1" name="name1" type="text" placeholder="name1">
                </div>
                <div>
                    <label>name2</label>
                    <input v-model="user.name2" name="name2" type="text" placeholder="name2">
                </div>
                <div>
                    <label>email</label>
                    <input v-model="email" name="email" type="email" placeholder="email">
                </div>
                <div>
                    <label>login_pwd</label>
                    <input v-model="user.login_pwd" name="login_pwd" type="password" placeholder="login_pwd">
                </div>

                <div>
                    <button type="submit">
                        サインアップ
                    </button>
                </div>
            </form>
        </div>
        <div v-else-if="presignupDone">
            仮登録が完了しました。メールをご確認ください。
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            presignupDone: false,
            email: null,
            user: {},
            error: null
        }
    },
    methods: {
        async signup() {
            try {
                const payload = {
                    email: this.email,
                    ext_info: {
                        ...this.user
                    },
                }
                // post data
                // 新規会員登録のリクエスト
                await this.$axios.$post('/rcms-api/13/member/invite', payload)
                this.presignupDone = true
            } catch (e) {
                console.error(e)
                this.error = 'エラーが発生しました。'
            }
        },
    },
}
</script>

<style scoped>
form>div {
    margin: 8px;
    display: flex;
    flex-direction: row;
}

form>div>* {
    display: flex;
    flex-direction: row;
    flex-basis: 100px;
}

form>div>*:nth-child(1) {
    flex: 0 0 100px;
    padding-right: 8px;
}

form>div>*:nth-child(2) {
    min-width: 0;
    flex: 1 100 auto;
}
</style>

/rcms-api/33/member_inviteの部分はご自身のエンドポイントのURLに変更してください。
以下同様に、ソースコード内のエンドポイントURLはご自身のエンドポイントURLに変更をお願いします。

本登録用のページ作成

/login/signup_pre_regist/done/ のディレクトリに_key.vue のファイルを作成します。

  • validate({ params })部分の記述で、keyがない場合や、keyの桁数が想定と異なる場合に404のページを表示します。
  • mounted($route)部分の記述で、URLにアクセス後自動でregisterUser()を呼び出します。
  • async registerUser()部分の記述でMember::inviteのエンドポイントからの情報取得と、Member::insertのエンドポイントへのリクエスト送付をします。
/login/signup_pre_regist/done/_key.vue
<template>
    <div>
        <div v-if="signupDone">
            登録が完了しました。
        </div>
        <p v-if="error" :style="{ color: 'red' }">
            {{ error }}
        </p>
    </div>
</template>

<script>
export default {
    validate({ params }) {
        return /[!-~]{32}/.test(params.key)
    },
    data() {
        return {
            signupDone: false,
            error: null
        }
    },
    methods: {
        async registerUser() {
            // obtain POSTed form values
            const invitationRes = await this.$axios.post(
                '/rcms-api/13/member/invite',
                {
                    email_hash: this.$route.params.key
                }
            );
            try {
                const payload = {
                    email: invitationRes.data.data.email,
                    ...invitationRes.data.data.ext_info
                }
                // request registration to an API endpoint using custom function
                await this.$axios.post('/rcms-api/13/member/regist', payload);
                this.signupDone = true
            } catch (error) {
                this.error = error.response.data.errors[0].message
            }
        }
    },
    mounted($route) {
        this.registerUser();
    }
}
</script>

動作確認

動作の確認をして、想定通りの動作でメンバーが登録できていることを確認します。

仮登録メール送信

Image from Gyazo

仮登録メールの内容確認

Image from Gyazo

本登録

Image from Gyazo

以上で、仮登録機能の実装が完了です。

関連ドキュメント

お探しのページは見つかりましたか?解決しない場合は、問い合わせフォームからお問い合わせいただくか、Slackコミュニティにご参加ください。