- 投稿日:2019-05-03T21:46:07+09:00
モダンな技術を全く知らないSIer5年目題Webサービスを作ることになったため0から勉強する〜Nuxt +メール認証+パスワードリセット〜
はじめに
現在SIer5年目でjavascript(Jqueryのみ)、PHP(フレームワーク無し)を2年ほど、C#(Windowsアプリ)3年ほどやってきました。
色々なご縁があり、個人で最近Webサービスの立ち上げをやることになったのですが何せ本当にWebサービスを立ち上げるための知識がほぼ0に等しいですただ今後のキャリアを考えた時に今のままではいけないと思いチャレンジすることにしました。
まずは最初に技術を習得しないといけないので、学ぶ&アウトプットするために毎回投稿していこうと思います。
今後身についていこうと思ってるのは下記のような技術です。
AWS
Docker
CI/CD環境の構築
Laravel
Nuxt.js
今回はLaravel+Nuxtについて学んでいきます。今回学ぶこと
Laravel+Nuxtでのメール認証機能とパスワードリセット機能を作成していこうかと思います。
今回はLaravel API側の実装をしていきます参考サイト
メール認証の概要は個々がわかりやっすかったです。
前提
Laravel 5.8
Nuxt 2.5.4
jwt-authメール認証とパスワードリセットのAPI側実装はこちらで実装してるのでこちらを参照ください
最終的なソースコードはこちらになります。
※今回は、Nuxt側の実装でLaravel側も変更している箇所もあるのでそちらもソースコード確認してもらえたらと思います。Nuxt側のvueファイルを作成する
フロント側はメール認証+パスワード再発行を実現するための画面とミドルウェアを作成します。
vue_file 概要 client/pages/auth/resetpassword.vue パスワードを変更する画面、パスワード変更時にトークンも一緒に送る client/pages/auth/resendverify.vue メール認証のリンクを送るための画面 client/pages/auth/forgotpassword.vue メールアドレスを入力し、パスワード再発行メールを送信する画面 client/pages/auth/emailverification.vue メール認証中の際に表示する画面 client/middleware/emailVerify.js メール認証済みかチェックを行うミドルウェア パスワードリセットを実装する
まずはパスワードリセットを実装するにあたっての処理の流れはこんな感じになります。
- ログイン画面から
Forgot Your Password
リンクをクリックし、パスワード再発行のメールアドレスを入力するforgotpassword.vue
を表示する- メールアドレスを入力し、再発行ボタンを押下すると
localhost/api/auth/password/email
APIに対してリクエストが投げられ指定したアドレスにパスワード再発行メールを送る- メールのリンクをクリックすると
resetpassword.vue
を表示し、リセットするパスワードを入力し、リンクに乗ってるqueryURLに対してリクエストを投げる- パスワードリセットが完了したら、ログイン画面に遷移する
ログイン画面から
forgotpassword.vue
に遷移するリンクを作成client/pages/auth/login.vue<div class="form-group"> <input type="submit" value="Login" class="btn btn-default w-100"> <nuxt-link class="nav-link" to="/auth/forgotpassword">Forgot Your Password</nuxt-link> </div>パスワードリセット対象のメールアドレス入力画面を実装する
client/pages/auth/forgotpassword.vue<template> <div class="container"> <div class="col-md-6 offset-md-3"> <div class="card mt-4"> <div class="card-header"> <p class="mb-0">ForgotPassword</p> </div> <div class="card-body"> <b-alert variant="success" v-model="showSuccessAlert">I have sent a password reissue email</b-alert> <!-- パスワードリセットメールを送れたことをメッセージで表示する --> <form @submit.prevent="ReSendVerifyEmail"> <div class="form-group"> <label>Email</label> <input v-model="form.email" type="email" class="form-control" :class="{ 'is-invalid': errors.email }" placeholder="Email"> </div> <div class="form-group"> <input type="submit" value="SendResetLinkEmail" class="btn btn-default w-100"> </div> </form> </div> </div> </div> </div> </template> <script> export default { middleware: 'guest', //ログインであればリダイレクトする data() { return { form: { email: '', }, showSuccessAlert: false } }, methods: { async ReSendVerifyEmail(){ // パスワードリセットのメール送信APIを実行する await this.$axios.post('/auth/password/email', this.form) .then(data => { // 送信完了メッセージ表示 this.showSuccessAlert = true; }) .catch(err=> { console.log(err); }); } } } </script>リセットするパスワード入力する画面
client/pages/auth/resetpassword.vue<template> <div class="container"> <div class="col-md-6 offset-md-3"> <div class="card mt-4"> <div class="card-header"> <p class="mb-0">Register</p> </div> <div class="card-body"> <form @submit.prevent="ResetPassword"> <!-- 標準のsubmitは実行しない --> <div class="form-group"> <label>Email</label> <input v-model="form.email" type="email" class="form-control" :class="{ 'is-invalid': errors.email }" placeholder="Email"> <div class="invalid-feedback" v-if="errors.email"> {{ errors.email[0] }} </div> </div> <div class="form-group"> <label>Password</label> <input v-model="form.password" type="password" class="form-control" :class="{ 'is-invalid': errors.password }" placeholder="Password"> <div class="invalid-feedback" v-if="errors.password"> {{ errors.password[0] }} </div> </div> <div class="form-group"> <label>Password Confirmation</label> <input v-model="form.password_confirmation" type="password" class="form-control" :class="{ 'is-invalid': errors.password }" placeholder="Password"> <div class="invalid-feedback" v-if="errors.password"> {{ errors.password[0] }} </div> </div> <div class="form-group"> <input type="submit" value="Register" class="btn btn-default w-100"> </div> </form> </div> </div> </div> </div> </template> <script> export default { middleware: 'guest', //ログイン状態であればリダイレクトする data() { return { form: { email: '', // リセット対象のメールアドレス password: '', // 新しいパスワード password_confirmation: '', // 新しいパスワード確認 token: '' // パスワードリセット実行するための一時的なトークン }, requestUrl: '' } }, created() { this.setQuery() }, methods: { async ResetPassword(){ // パスワードリセットリクエストを投げる関数 await this.$axios.$post(this.requestUrl, this.form) .then(data => { this.$router.push('/auth/login'); }) .catch(err=> { console.log(err); }); }, setQuery() { // getリクエストのパラメータを取得する関数 this.requestUrl = this.$route.query.queryURL || ''; // パスワードリセットAPIのURL this.form.token = this.$route.query.token || ''; // パスワードリセットするために必要なToken }, } } </script>メール認証を実装する
メール認証を実装するにあたっての処理流れはこんな感じになります
- ユーザ登録後にメール認証するためのメールを送信する
- メールからメール認証画面に遷移する
- メール認証画面では、queryURLにそのままリクエストを投げてメール認証を行い、成功したら画面遷移を行う
client/pages/auth/emailverification.vue<template> <div class="container"> <div class="col-md-6 offset-md-3"> <div class="card mt-4"> <div class="card-header"> <p class="mb-0">During Verification Your Email Address</p> </div> <div class="card-body"> <label>Validating your email address.</label> </div> </div> </div> </div> </template> <script> export default { middleware: 'auth', //未ログイン状態であればリダイレクトする data() { return { queryURL: '' } }, async mounted() { const queryURL = this.$route.query.queryURL || ''; if (queryURL != '') { await this.$axios.$get(queryURL) .then(data => { this.$auth.fetchUser(); // メール認証が完了したため、ユーザ情報を再取得する this.$router.push({name: 'index'}); }) .catch(err => { alert('メール認証が失敗しました。再度メール認証を行ってください。'); this.$router.push('/auth/resendverify'); }); } }, } </script>メール認証チェックを行い、メール認証が必要な画面にアクセスした場合、認証メールを再送する画面にリダイレクトする
メール認証チェックを行うミドルウェアを実装する
email_verified_at
はLaravelのUserモデルにはデフォルト項目であり
メール認証された場合はここに日時が入ってるため
null
の場合は未認証と判断し、リダイレクトを行うclient/middleware/emailVerify.js//メールアドレスが認証されていなければ、メール認証の送信画面に遷移する export default function({ store, redirect, app }) { if(app.$auth.user['email_verified_at'] == null) { return redirect('/auth/resendverify'); } }メール認証チェックを行う
ダッシュボードは未認証ユーザはアクセスできないようにする
client/pages/dashboard.vue<template> <div class="container"> <h1>Welcome to the dashboard</h1> </div> </template> <script> export default { middleware: 'auth', middleware: 'emailVerify' // メール認証チェックを行う } </script>認証メールの再送信画面を実装する
client/pages/auth/resendverify.vue<template> <div class="container"> <div class="col-md-6 offset-md-3"> <div class="card mt-4"> <div class="card-header"> <p class="mb-0">Verify Your Email Address</p> </div> <div class="card-body"> <b-alert variant="success" v-model="showSuccessAlert">I have sent a password reissue email</b-alert> <label>Email verification has not been completed yet. Please press the button below to complete e-mail authentication</label> <div> <b-button block variant="primary" @click="ReSendVerifyEmail">Verify Email</b-button> </div> </div> </div> </div> </div> </template> <script> export default { middleware: 'auth', //ログインしてなければリダイレクトする data() { return { form: { email: '', }, showSuccessAlert: false, } }, methods: { async ReSendVerifyEmail(){ await this.$axios.post('/auth/email/resend', this.form) .then(data => { this.showSuccessAlert = true; }) .catch(err=> { console.log(err); }); }, } } </script>まとめ
フロント側はLaravelの
make:auth
で作成されるViewを参考に作りました
独学なので、おそらくもっと良い実装方法はあるかと思います。。。
もしこうした方がいいとかこのサイトは参考になるよなどあれば教えてもらえると幸いです。あと、ログイン情報を保持するなどの機能はまだ実装してないのでそちらも実装できたらと思います。
- 投稿日:2019-05-03T07:07:43+09:00
Laradockによるlaravel開発環境構築
はじめに
今更ですがLaravelをLaradockを使い環境構築してみます。
(この投稿は自分用メモでもあります。)前提
docker-composeコマンドが使える
> docker-compose --version docker-compose version 1.23.2, build 1110ad01gitコマンドが使える
> git --version git version 2.21.0.windows.1ちなみにPCはWindows10 proを使用しています。
1.作業ディレクトリの作成&Laradockのクローン
# 作業ディレクトリを作成 > mkdir dockerworkspace # 作業ディレクトリに移動 > cd dockerworkspace # GitからLaradockをダウンロード > git clone https://github.com/LaraDock/laradock.git2.「.env」ファイルの作成
# laradockディレクトリに移動 > cd laradock # env-exampleをコピーし.envファイル作成 > cp env-example .env3.コンテナの起動
# laradockディレクトリ上で入力 # コンテナの起動 > docker-compose up -d nginx Recreating laradock_docker-in-docker_1 ... done Recreating laradock_workspace_1 ... done Recreating laradock_php-fpm_1 ... done Recreating laradock_nginx_1 ... doneコンテナの起動を確認してみましょう。
# laradockディレクトリ上で入力 # コンテナの一覧を表示 > docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------------------------------ laradock_docker-in-docker_1 dockerd-entrypoint.sh Up 2375/tcp laradock_mysql_1 docker-entrypoint.sh mysqld Exit 255 0.0.0.0:3306->3306/tcp, 33060/tcp laradock_nginx_1 /bin/bash /opt/startup.sh Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp laradock_php-fpm_1 docker-php-entrypoint php-fpm Up 9000/tcp laradock_phpmyadmin_1 /run.sh supervisord -n -j ... Exit 255 0.0.0.0:8080->80/tcp, 9000/tcp laradock_redis_1 docker-entrypoint.sh redis ... Exit 255 0.0.0.0:6379->6379/tcp laradock_workspace_1 /sbin/my_init Up 0.0.0.0:2222->22/tcpStateがupになっていれば起動していることになります。
http://localhostにアクセスします。
nginxの起動を確認できました。Not Foundは後ほど対処します。
4.Laravelプロジェクトの作成
laradock_workspace_1にアクセスしLaravelアプリケーションを作成します。
# laradockディレクトリ上で入力 # workspaceコンテナにアクセス # root@xxxxxxxx:/var/www$ というディレクトリに入る > docker-compose exec --user=laradock workspace bash # Laravelアプリケーションの作成 # ここではsample_appという名前で作成 root@xxxxxxxx:/var/www$ composer create-project laravel/laravel sample_app5.nginxの設定ファイルの編集
root@xxxxxxxx:/var/www$ exit # laradockディレクトリ上で入力 # コンテナの停止 > docker-compose stop # laradockディレクトリ上で入力 # dockerworkspace/laradock/nginx/sitesの中のdefaul.confをdefault.conf.backup等の名前にしコピー > cd nginx/sites > cp default.conf default.conf.backup # 同じディレクトリにあるlaravel.conf.exampleの中のテキストをコピーし、default.confにペースト > cp laravel.conf.example default.confdockerworkspace/laradock/nginx/sites/default.confを編集します。
default.conf# 一部抜粋 server_name laravel.test; # root /var/www/laravel/public; # 変更前 root /var/www/sample_app/public; # 変更後 index index.php index.html index.htm;さらにlaradockディレクトリにある.env(はじめにコピーして作ったファイルですね)も編集します。
.env# 一部抜粋 ### Paths ################################################# # Point to the path of your applications code on your host # APP_CODE_PATH_HOST=../ # 変更前 APP_CODE_PATH_HOST=../sample_app # 変更後6.LaravelのWelcome画面を見る
> docker-compose up -d nginxhttp://localhostにアクセスします。
追記
MySQLに接続
設定ファイルの編集
Laradockの初期設定ではMySQLの最新が設定されており認証でエラーが出てしまうそうです。laradock/.envを編集します。
laradock/.env### MYSQL ################################################# # MYSQL_VERSION=latest # 変更前 MYSQL_VERSION=5.7 # 変更後Laravelの設定もします。sample_app/.envを編集します。
sample_app/.envDB_CONNECTION=mysql # DB_HOST=127.0.0.1 # 変更前 DB_HOST=mysql # 変更後 DB_PORT=3306 # DB_DATABASE=homestead # 変更前 # DB_USERNAME=homestead # 変更前 DB_DATABASE=default # 変更後 DB_USERNAME=default # 変更後 DB_PASSWORD=secretこれでMySQLへの接続ができます。
migrateしてみる
# laradockディレクトリ上で入力 > docker-compose up -d nginx mysql # 省略 > docker-compose exec --user=laradock workspace bash root@xxxxxxxx:/var/www$ php artisan migrate Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_tableDBを見てみる
# laradockディレクトリ上で入力 > docker-compose exec mysql bash root@xxxxxxxxxx:/# mysql -udefault -psecret # 省略 mysql> use default; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql > show tables; +-------------------+ | Tables_in_default | +-------------------+ | migrations | | password_resets | | users | +-------------------+ 4 rows in set (0.00 sec)最後に
DockerはLaradockでしか触ったことがないので間違った認識、改善点等ありましたらご指摘お願いいたします。
Docker勉強しよう、、、。