Laravel ログイン時のメール認証機能

3 min read読了の目安(約3500字

内容

Laravel標準機能の認証に加え、メール認証を行えるようにする。
メール認証に関しての記事はいくつかあるが、Laravel標準機能を利用してシンプルかつエラーのない実装を目指す。
メールの送信元はGmailを利用。
Herokuデプロイ後にエラーが出たので、そこも解説。

メール認証機能

User.phpの編集

//User.php
class User extends Authenticatable implements MustVerifyEmail

User.phpのclass~のあとにimplements MustVerifyEmailを追加する

Routeの編集


//web.php
Auth::routes(['verify' => true]);

Laravel標準のログイン機能を実装していれば、Auth::routes();ができているはずなので、上記のように変更。

//web.php
Route::middleware('verified')->group(function() {
//メール認証が完了した場合のみ、実行できるRoute
});

このrouteにアクセスした場合、↓が表示される

Bladeの日本語化

上記の写真の内容はviews/auth/verify.blade.phpで編集できる。
今回は日本語に直しただけのもの

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">メールアドレス認証はお済みですか?</div>

                <div class="card-body">
                    @if (session('resent'))
                        <div class="alert alert-success" role="alert">
                            新規認証メールを再送信しました!
                        </div>
                    @endif

                    このページを閲覧するには、Eメールによる認証が必要です。
                    もし認証用のメールを受け取っていない場合、
                    <form class="d-inline" method="POST" action="{{ route('verification.resend') }}">
                        @csrf
                        <button type="submit" class="btn btn-link p-0 m-0 align-baseline">こちらのリンク</button>をクリックして、認証メールを受け取ってください。
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

参照記事

https://webxreal.com/laravel-auth/

.envの編集

今回はGmailを利用する

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=hoge@gmail.com
MAIL_PASSWORD=アプリパスワード(詳しくは後述)
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=hoge@gmail.com
MAIL_FROM_NAME=任意のアプリ名

MAIL_ENCRYPTIONを記入していない例もいくつか見受けられたが、nullだと送信できなかったので書いたほうがよいと思われる。
tlsとは何かについては↓を参照

https://www.idcf.jp/rentalserver/aossl/basic/ssl-tls/

Gmailのアプリパスワードについて

MAIL_PASSWORDに記入する値はGoogleアカウントのログインパスワードではないことに注意
ここからはアプリパスワードの取得とGoogleアカウントのセキュリティ設定を行う

Googleアカウントの管理画面を開き、セキュリティをクリック

二段階認証をオンにする

その後アプリパスワードの設定ができるようになる。
その先の設定は、メールとお使いの機種を選択すればよい
パスワードは1度しか確認できないので注意する

ここで取得した16桁のパスワードをMAIL_PASSWORDに記入する

これでも送信できない場合は

セキュリティにのところにあるこれをオンにする。

Googleアカウントの設定に関しては↓記事参照

https://snome.jp/framework/laravel-mail-submit/

以上でメール認証機能の実装は完了です

Herokuへのデプロイ後

Herokuへのデプロイ後、届いたメールをクリックすると403エラー invaid signatureが表示された
原因:サイトのURLがhttps化されているのに、メールのURLがhttpになっていること
解決法

///Middleware/TrustProxies.php
<?php

namespace App\Http\Middleware;

use Fideloper\Proxy\TrustProxies as Middleware;
use Illuminate\Http\Request;

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array|string
     */
    protected $proxies= '*'; //ここを編集するだけ

    /**
     * The headers that should be used to detect proxies.
     *
     * @var int
     */
    protected $headers = Request::HEADER_X_FORWARDED_ALL;
}

参考記事

https://qiita.com/Takagi-Yuya/items/47e80036bf15bbd0e50c
https://qiita.com/tsukiwakka/items/db6c7bb6b538075b1db5