Laravel標準の登録画面をカスタマイズしたいんだけど、うまくできない!!
本記事はこういった悩みに対しての記事です!
この記事を書いている僕(@Shoot58153748)は、
2020年3月現在メガベンチャーの社内スタートアップの部署で
エンジニア(1年目)をしており、
プログラミング未経験からメガベンチャーへの転職を成功させた経験・ノウハウ
Webエンジニアになってから学んだこと
をブログにまとめています。Laravel
でVuetify
を使う方法に関してはこちらの記事で解説しているので参考にしてください!
※アプリの環境設定はこちらの記事を踏襲しています。
今回はvuetify
コンポーネントの使い方に重きを置いて
ツイート画面(Vueコンポーネント)を作っていきます。
学びポイントを以下にまとめました。
是非参考にしてください!
今回のポイント
- Vuetifyで登録画面カスタマイズ
- 落とし穴1(パスワードバリデーション)
- 落とし穴2(CSRF対策)
ツイッター風SNSアプリ作成チュートリアル
https://kumatetsublog.com/laravel-tutorial-web-application
Github
https://github.com/Shuto-san/laravel-vue-docker
目次
Vuetifyで登録画面(コンポーネント)を実装
画面イメージ(Vuetify導入後)
実装(Vueコンポーネント)
最初に登録画面(コンポーネント)の全コードを載せます!
ファイル名:resouces/js/conponents/RegisterComponent.vue
Template部分
<template>
<v-app>
<v-content>
<v-container
class="fill-height"
fluid
>
<v-row
align="center"
justify="center"
>
<v-col
cols="12"
sm="8"
md="4"
>
<v-card class="elevation-12">
<v-toolbar
color="primary"
dark
flat
>
<v-toolbar-title>Register form</v-toolbar-title>
<v-spacer />
</v-toolbar>
<v-card-text>
<v-form>
<v-text-field
label="Name"
name="name"
prepend-icon="person"
type="text"
v-model="name"
/>
<v-text-field
label="Email"
name="email"
prepend-icon="email"
type="email"
v-model="email"
/>
<v-text-field
label="Password"
name="password"
prepend-icon="lock"
type="password"
v-model="password"
/>
<v-text-field
label="Password Confirmation"
name="password_confirmation"
prepend-icon="lock"
type="password"
v-model="password_confirmation"
/>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn @click="postRegister" color="primary">Register</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</v-content>
</v-app>
</template>
SCRIPT部分
<script>
export default {
props: {
source: String,
},
data () {
return {
name: "",
email: "",
password: "",
password_confirmation: ""
}
},
methods: {
postRegister(){
axios.post(window.location.origin + `/register`, {
name: this.name,
email: this.email,
password: this.password,
password_confirmation: this.password_confirmation
})
.then(response => {
window.location.href = window.location.origin + `/tweet/index`;
})
.catch(error => {
console.log("validation error");
});
}
}
}
</script>
画面設計
ログイン画面実装時と同じく、以下のような構成になっております。
ログイン画面と変わる部分は、v-card-text
の中のv-text-field
の数です。
ログイン画面は、
メールアドレス(email)
パスワード(password)
今回の登録画面は加えて、
名前(name)
パスワード確認(password_confirmation)
が必要です。特に最後の項目が抜けると僕のようにハマります。(以下詳細)
落とし穴ポイント1(バリデーション)
以下のエラーログに小一時間悩まされたので共有しておきます。
[2020-03-26 23:59:47] local.ERROR: Error occured : request_url=http://127.0.0.1:8000/register, errorMessage=The given data was invalid.
The given data was invalid…?
何だろうこれ、、、とか思いつつ、ブラウザのデベロッパーツールのNetworkを見ると、/register
のPOSTに対して、
422 error
が返ってきていることを発見。
「Laravel 422エラー」みたいな感じで適当にググっていたら、
どうやらバリデーションに問題があるらしいということがわかりました。
以下がLaravel標準のバリデーション内容です。
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
どこのバリデーションに引っかかっているのか。。。
文字数は問題ないし、emailもユニークだし、、、confirmed
ってなんだ??
Laravel標準の登録画面を見てみると、、、password_confirmation
という項目が!
バリデーションでconfirm
を設定した場合、
XXXX_confirmationというフィールドを用意して、XXXX(パスワード)と一致する必要がありました!
僕は最初、name, email, passwordの3要素しか用意してなかったのでバリデーションにかかっていたのですね。
Laravel標準の登録画面をカスタマイズするときは、
パスワード確認のフィールドを忘れないようにしましょう。
落とし穴ポイント2(CSRF対策)
Laravelの標準機能であるCSRF
対策が必要で、
以下のコードはCSRF
トークンをaxios
のヘッダーに付与する処理です。
この処理がないとaxios
でポストする際にエラーになってしまうので、
コンポーネントを読み込むJSファイルに必ず含めましょう。
const token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found');
}
まとめ
以上、Laravel×Vuetifyで登録画面をカスタマイズしました。
ログイン画面もそうですが、
Laravel標準のAuth機能は便利な分、カスタマイズに迷うことがあります。
今回紹介した落とし穴に注意して是非とも画面をカスタマイズしてみましょう!
最後に今回のポイントをまとめます。
ポイント
- Vuetifyで登録画面カスタマイズ
- 落とし穴1(パスワードバリデーション)
- 落とし穴2(CSRF対策)
やっとWebアプリとして形になってきたので、
そろそろVPSにデプロイすることも考えています。
是非楽しみに待っていてください!
もし、こんな機能を実装してほしいというリクエストがあったら
連絡ください!
実装して皆さんに共有したいと思います。
それではまた!
コメント