MultiAuthにEmailVerificationを対応させる実装メモ。
【laravel5.7】 MultiAuthログインの続きとして書きます。
MultiAuthなしの実装メモは別記事で書いているので、参考になれば、、、
【laravel5.7】 Email Verificationの使い方
やりたいこと
MultiAuth(Admin/User)のUserのみにEmail Verificationを対応させたい。
環境
MacOS 10.14.3
VisualStudio
laravel 5.7
Email Verificationを使えるようにする
MustVerifyEmailの追加
app/User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
+class User extends Authenticatable implements MustVerifyEmail
{
ルーティング設定
routes/web.php
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
use Illuminate\Http\Request;
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
// User
Route::group(['namespace' => 'User','prefix'=>'user'],function(){
+ Route::get('/',function(){
+ return redirect()->to('user/home');
+ })->name('user');
// home
Route::get('home','HomeController@index')->name('user.home');
// login lgoout
Route::get('login','Auth\LoginController@showLoginForm')->name('user.login');
Route::post('login','Auth\LoginController@login')->name('user.login');
Route::post('logout','Auth\LoginController@logout')->name('user.logout');
// register
Route::get('register','Auth\RegisterController@showRegisterForm')->name('user.register');
Route::post('register','Auth\RegisterController@register')->name('user.register');
+ // emailverify
+ Route::middleware('throttle:6,1')->get('email/resend','Auth\VerificationController@resend')->name('user.verification.resend');
+ Route::middleware('throttle:6,1')->get('email/verify','Auth\VerificationController@show')->name('user.verification.notice');
+ Route::middleware('signed')->get('email/verify/{id}','Auth\VerificationController@verify')->name('user.verification.verify');
});
// Admin
以下省略
単体ログインのEmailVerificationのAuth:routes(['verify'=>true]);
を
MultiAuthでは上の(//emailverify以下
の部分)のように一つずつ書いていきます。
VerificationController.php
app/Http/Controllers/User/Auth/VerificationController.php
<?php
+namespace App\Http\Controllers\User\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\VerifiesEmails;
+use Illuminate\Http\Request;
class VerificationController extends Controller
{
/*
|--------------------------------------------------------------------------
| Email Verification Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling email verification for any
| user that recently registered with the application. Emails may also
| be re-sent if the user didn't receive the original email message.
|
*/
use VerifiesEmails;
/**
* Where to redirect users after verification.
*
* @var string
*/
+ protected $redirectTo = '/user/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
+ $this->middleware('auth:user');
$this->middleware('signed')->only('verify');
$this->middleware('throttle:6,1')->only('verify', 'resend');
}
+ public function show(Request $request)
+ {
+ return $request->user()->hasVerifiedEmail()
+ ? redirect($this->redirectPath())
+ : view('user.auth.verify');
+ }
}
HomeController.php
app/Http/Controllers/User/HomeController.php
public function __construct()
{
$this->middleware('auth:user');
+ $this->middleware('allVerified');
}
Middleware
AllEnsureEmailIsVerified.phpを作成します
terminal
php artisan make:middleware AllEnsureEmailIsVerified
app/Http/Middleware/AllEnsureEmailIsVerified.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Support\Facades\Auth;
class AllEnsureEmailIsVerified
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$guards = array_keys(config('auth.guards'));
foreach($guards as $guard) {
if($guard == 'user') {
if (Auth::guard($guard)->check()) {
if (! Auth::guard($guard)->user() ||
(Auth::guard($guard)->user() instanceof MustVerifyEmail &&
! Auth::guard($guard)->user()->hasVerifiedEmail())) {
// dd('ddd');
return $request->expectsJson()
? abort(403, 'Your email address is not verified.')
: Redirect::route('user.verification.notice');
}
}
}
}
return $next($request);
}
}
Kernel.php
app/Http/Kernel.php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
+ 'allVerified' => \App\Http\Middleware\AllEnsureEmailIsVerified::class,
];
verify.blade.php
views/user/auth/verify.blade.php
+@extends('layouts.user.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
{{ __('メールアドレスの認証をしてください。') }}
+ {{ __('もしメールを受け取ってないなら、<a href="{{ route('user.verification.resend') }}">ここをクリックしてください</a>。') }}
</div>
</div>
</div>
</div>
</div>
@endsection
メール内容をカスタマイズ
Notificationsの作成
terminal
php artisan make:notification UserVerifyEmailNotification
app/Notifications/UserVerifyEmailNotification.php
<?php
namespace App\Notifications;
use Illuminate\Auth\Notifications\VerifyEmail as VerifyEmailNotification;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\Lang;
class UserVerifyEmailNotification extends VerifyEmailNotification
{
public function toMail($notifiable)
{
if (static::$toMailCallback) {
return call_user_func(static::$toMailCallback, $notifiable);
}
return (new MailMessage)
->subject(Lang::getFromJson('USERメール確認'))
->line(Lang::getFromJson('クリックして認証してください.'))
->action(
Lang::getFromJson('メール認証'),
$this->verificationUrl($notifiable)
)
->line(Lang::getFromJson('もしこのメールに覚えが無い場合は破棄してください。'));
}
protected function verificationUrl($notifiable)
{
return URL::temporarySignedRoute(
'user.verification.verify', Carbon::now()->addMinutes(60), ['id' => $notifiable->getKey()]
);
}
}
User.php
UserVerifyEmailNotificationがメールで送信されるようにModelに設定します。
app/User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
+use App\Notifications\UserVerifyEmailNotification;
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
+ public function sendEmailVerificationNotification()
+ {
+ $this->notify(new UserVerifyEmailNotification);
+ }
}
動作確認
User
http://127.0.0.1:8000/user/register から新しくアカウントを登録します。
こうなれば成功です。
まだ英語の部分があるので、その辺の設定は後々設定しようと思います。
Adminでも実装したい場合はこれと同様に編集すればOK。
とりあえず以上です。