Multi AuthとSocial Loginを作ってみた。
最近余談ばかりなので今回は簡潔にするつもり。
今回デリケートな内容ですのでデモはありません。
またSocial Loginには各SNSアカウントとAPI_KEY/API_SECRETが必要です。
各種設定が必要になってまいります。
またGithub等にUpする際はアカウント関連は.gitignore等で.envを除外してください。
使い方
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
## 使い方 ### Download git clone https://github.com/Lara-Bell/Multi-Auth_Social-Login.git multi_auth cd multi_auth ### Install composer install cp .env.example .env php artisan key:generate php artisan migrate ### NPM Install npm install bower install bootstrap-social npm run dev ## Social Login ### .env Edit TWITTER_CLIENT_ID= TWITTER_CLIENT_SECRET= TWITTER_URL_CALLBACK=http://YOUR_DOMAIN/login/twitter/callback GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= GOOGLE_URL_CALLBACK=http://YOUR_DOMAIN/login/google/callback |
またLaravelのインストール・データベース設定は以前の記事を見てください。
流れ
Model->App\Config->Controller->route->view
こんな形で説明
Multi Auth
Laravel 5.2から実装された機能
Admin や ECなどではSeller / Buyerアカウントなどに派生できる基礎的な部分です。
Model
Auth作成
1 |
php artisan make:auth |
ModelとMigration File作成
1 |
php artisan make:model Admin -m |
App\Admin.phpを下記に変更
sendPasswordResetNotificationファンクションはNotificationで説明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?php namespace App; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; use App\Notifications\AdminResetPasswordNotification; class Admin extends Authenticatable { use Notifiable; protected $guard = 'admin'; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'email', 'password', 'role', ]; /** * The attributes that should be hidden for arrays. * * @var array */ protected $hidden = [ 'password', 'remember_token', ]; public function sendPasswordResetNotification($token) { $this->notify(new AdminResetPasswordNotification($token)); } } |
Migration File
user
Social LoginのためにEmailとPasswordをnullable指定
通常のAuth登録時はControllerのバリデーションする。
1 2 3 4 5 6 7 8 9 |
Schema::create('users', function (Blueprint $table) { $table->increments('id')->unsigned(); $table->string('name'); $table->string('email')->unique()->nullable(); $table->string('password')->nullable(); $table->rememberToken(); $table->timestamps(); $table->softDeletes(); }); |
adminsテーブルを作成
権限の細分化するためのroleカラム作成
1 2 3 4 5 6 7 8 9 10 |
Schema::create('admins', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('email')->unique(); $table->string('role'); $table->string('password'); $table->rememberToken(); $table->timestamps(); $table->softDeletes(); }); |
Migration
1 |
php artisan migrate |
config\auth.php
config\auth.phpでMiddlewareでAdmin権限を作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
'guards' => [ ... ... 'admin' => [ 'driver' => 'session', 'provider' => 'admins', ], 'admin-api' => [ 'driver' => 'token', 'provider' => 'admins', ], ] 'providers' => [ ... ... 'admins' => [ 'driver' => 'eloquent', 'model' => App\Admin::class, ], ] 'passwords' => [ ... ... 'admins' => [ 'provider' => 'admins', 'table' => 'password_resets', 'expire' => 15, ], ], |
Controller
AdminController作成
1 |
php artisan make:controller AdminController |
app\Http\Controllers\AdminController編集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class AdminController extends Controller { /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('auth:admin'); } /** * Show the application dashboard. * * @return \Illuminate\Http\Response */ public function index() { return view('admin'); } } |
app\Http\Controllers\Auth下のファイルを
app\Http\Controllers\Auth\Adminを作りコピペ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
<?php namespace App\Http\Controllers\Auth\Admin; //編集 use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\SendsPasswordResetEmails; use Illuminate\Support\Facades\Password; //追加 use Illuminate\Http\Request; //追加 class ForgotPasswordController extends Controller { /* |-------------------------------------------------------------------------- | Password Reset Controller |-------------------------------------------------------------------------- | | This controller is responsible for handling password reset emails and | includes a trait which assists in sending these notifications from | your application to your users. Feel free to explore this trait. | */ use SendsPasswordResetEmails; /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('guest:admin'); // 編集 } //追加 /** * Get the broker to be used during password reset. * * @return \Illuminate\Contracts\Auth\PasswordBroker */ protected function broker() { return Password::broker('admins'); } /** * Display the form to request a password reset link. * * @return \Illuminate\Http\Response */ public function showLinkRequestForm() { return view('auth.admin.passwords.email'); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
<?php namespace App\Http\Controllers\Auth\Admin; //編集 use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; //追加 use Illuminate\Support\Facades\Auth; //追加 class LoginController extends Controller { /* |-------------------------------------------------------------------------- | Login Controller |-------------------------------------------------------------------------- | | This controller handles authenticating users for the application and | redirecting them to your home screen. The controller uses a trait | to conveniently provide its functionality to your applications. | */ use AuthenticatesUsers; /** * Where to redirect users after login. * * @var string */ protected $redirectTo = '/admin'; //編集 /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('guest:admin')->except('logout'); //編集 } /** * Show the application's login form. * * @return \Illuminate\Http\Response */ public function showLoginForm() { return view('auth.admin.login'); //編集 } //下記追加 /** * Handle a login request to the application. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse */ public function login(Request $request) { // Validate the form data $this->validate($request, [ 'email' => 'required|email', 'password' => 'required|min:6' ]); if(Auth::guard('admin')->attempt( [ 'email' => $request->email, 'password' => $request->password ], $request->remember)){ return redirect()->intended(route('admin.dashboard')); } return redirect()->back()->withInput($request->only('email', 'remember')); } /** * Log the user out of the application. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function logout() { Auth::guard('admin')->logout(); //編集 return redirect('/'); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
<?php namespace App\Http\Controllers\Auth\Admin; //編集 use App\Admin; //変更 use App\Http\Controllers\Controller; use Illuminate\Support\Facades\Validator; use Illuminate\Foundation\Auth\RegistersUsers; use Illuminate\Support\Facades\Auth; //追加 class RegisterController extends Controller { /* |-------------------------------------------------------------------------- | Register Controller |-------------------------------------------------------------------------- | | This controller handles the registration of new users as well as their | validation and creation. By default this controller uses a trait to | provide this functionality without requiring any additional code. | */ use RegistersUsers; /** * Where to redirect users after registration. * * @var string */ protected $redirectTo = '/admin'; //編集 /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('guest:admin'); //編集 } /** * Get a validator for an incoming registration request. * * @param array $data * @return \Illuminate\Contracts\Validation\Validator */ protected function validator(array $data) { return Validator::make($data, [ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'role' => 'required|string|max:255', //追加 'password' => 'required|string|min:6|confirmed', ]); } /** * Create a new user instance after a valid registration. * * @param array $data * @return \App\User */ protected function create(array $data) { return Admin::create([ 'name' => $data['name'], 'email' => $data['email'], 'role' => $data['role'], //追加 'password' => bcrypt($data['password']), ]); } //追加 /** * Show the application registration form. * * @return \Illuminate\Http\Response */ public function showRegistrationForm() { return view('auth.admin.register'); } /** * Get the guard to be used during registration. * * @return \Illuminate\Contracts\Auth\StatefulGuard */ protected function guard() { return Auth::guard('admin'); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
<?php namespace App\Http\Controllers\Auth\Admin; //編集 use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\ResetsPasswords; use Illuminate\Http\Request; //追加 use Illuminate\Support\Facades\Password; //追加 use Illuminate\Support\Facades\Auth; //追加 class ResetPasswordController extends Controller { /* |-------------------------------------------------------------------------- | Password Reset Controller |-------------------------------------------------------------------------- | | This controller is responsible for handling password reset requests | and uses a simple trait to include this behavior. You're free to | explore this trait and override any methods you wish to tweak. | */ use ResetsPasswords; /** * Where to redirect users after resetting their password. * * @var string */ protected $redirectTo = '/admin'; //編集 /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('guest:admin'); //編集 } //追加 /** * Get the broker to be used during password reset. * * @return \Illuminate\Contracts\Auth\PasswordBroker */ public function broker() { return Password::broker('admins'); } /** * Get the guard to be used during password reset. * * @return \Illuminate\Contracts\Auth\StatefulGuard */ public function guard() { return Auth::guard('admin'); } /** * Display the password reset view for the given token. * * If no token is present, display the link request form. * * @param \Illuminate\Http\Request $request * @param string|null $token * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function showResetForm(Request $request, $token = null) { return view('auth.admin.passwords.reset')->with( [ 'token' => $token, 'email' => $request->email ] ); } } |
Notification
app\Notification\AdminResetPasswordNotification.php作成
Adminのパスワードリセットする際の設定ファイル
基本User AuthのオーバーライドでAdmin向けに変更したい内容を編集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
<?php namespace App\Notifications; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Notification; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; class AdminResetPasswordNotification extends Notification { use Queueable; public $token; /** * Create a new notification instance. * * @return void */ public function __construct($token) { $this->token = $token; } /** * Get the notification's delivery channels. * * @param mixed $notifiable * @return array */ public function via($notifiable) { return ['mail']; } /** * Get the mail representation of the notification. * * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */ public function toMail($notifiable) { return (new MailMessage) ->line('You are receiving this email because we received a password reset request for your account.') ->action('Admin Reset Password', route('admin.password.reset', $this->token)) ->line('If you did not request a password reset, no further action is required.'); } /** * Get the array representation of the notification. * * @param mixed $notifiable * @return array */ public function toArray($notifiable) { return [ // ]; } } |
Exceptions/Handler.php
例外処理 下記追加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
use Illuminate\Auth\AuthenticationException; protected $dontReport = [ \Illuminate\Auth\AuthenticationException::class, \Illuminate\Auth\Access\AuthorizationException::class, \Symfony\Component\HttpKernel\Exception\HttpException::class, \Illuminate\Database\Eloquent\ModelNotFoundException::class, \Illuminate\Session\TokenMismatchException::class, \Illuminate\Validation\ValidationException::class, ]; /** * Convert an authentication exception into an unauthenticated response. * * @param \Illuminate\Http\Request $request * @param \Illuminate\Auth\AuthenticationException $exception * @return \Illuminate\Http\Response */ protected function unauthenticated($request, AuthenticationException $exception) { if ($request->expectsJson()) { return response()->json(['error' => 'Unauthenticated.'], 401); } $guard = array_get($exception->guards(), 0); switch ($guard) { case 'admin': $login = 'admin.login'; break; default: $login = 'login'; break; } return redirect()->guest(route($login)); } |
route
route\web.php編集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// 追加 Route::get('/home', 'HomeController@index')->name('home'); Route::get('/users/logout', 'Auth\LoginController@userLogout')->name('user.logout'); Route::prefix('admin')->group(function(){ Route::get('/', 'AdminController@index')->name('admin.dashboard'); Route::get('/login', 'Auth\Admin\LoginController@showLoginForm')->name('admin.login'); Route::post('/login', 'Auth\Admin\LoginController@login')->name('admin.login.submit'); // Admin Register // Route::get('register','Auth\Admin\RegisterController@showRegistrationForm')->name('admin.register'); // Route::post('register','Auth\Admin\RegisterController@register'); Route::get('/logout', 'Auth\Admin\LoginController@logout')->name('admin.logout'); Route::prefix('password')->group(function(){ Route::post('/email', 'Auth\Admin\ForgotPasswordController@sendResetLinkEmail')->name('admin.password.email'); Route::get('/reset', 'Auth\Admin\ForgotPasswordController@showLinkRequestForm')->name('admin.password.request'); Route::post('/reset', 'Auth\Admin\ResetPasswordController@reset'); Route::get('/reset/{token}', 'Auth\Admin\ResetPasswordController@showResetForm')->name('admin.password.reset'); }); }); |
view
resources/views/auth下のファイルを/resources/views/auth/adminにコピペ
resources/views/components/who.blade.phpをデバック用に作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
@if (Auth::guard('web')->check()) <p class="text-success"> You are Logged In as a <strong>USER</strong> </p> @else <p class="text-danger"> You are Logged Out as a <strong>USER</strong> </p> @endif @if (Auth::guard('admin')->check()) <p class="text-success"> You are Logged In as a <strong>ADMIN</strong> </p> @else <p class="text-danger"> You are Logged Out as a <strong>ADMIN</strong> </p> @endif |
Home.blade.phpとwelcome.blade.phpに下記追加
1 2 3 4 |
<div class="panel-body"> @component('components.who') @endcomponent </div> |
これでUserにログインしているかAdminにログインしているか確認できます。
resources/views/admin.blade.php作成
Login後のページ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="panel panel-default"> <div class="panel-heading">ADMIN Dashboard</div> <div class="panel-body"> @component('components.who') @endcomponent </div> </div> </div> </div> </div> @endsection |
resources/views/auth/admin下のファイルを編集する。
基本編集は不要で表示をUserからAdminに変更などを行う。
routeヘルパー先をすべてadminのnameに変更する。
route(‘admin.login’)はroute/web.phpの最後のnameと一致させる。下記のような設定
1 |
<form class="form-horizontal" method="POST" action="{{ route('admin.login') }}"> |
1 2 3 |
<a class="btn btn-link" href="{{ route('admin.password.request') }}"> Forgot Your Password? </a> |
.env
メールが飛ぶかどうかの確認。
今回はGmailでテストしました。
.envのmail設定を下記に変更
1 2 3 4 5 6 7 8 |
MAIL_DRIVER=smtp MAIL_HOST=smtp.gmail.com MAIL_PORT=587 MAIL_FROM_ADDRESS= MAIL_FROM_NAME=MAIL_NAME MAIL_USERNAME=YOUR_GMAIL_ADDRESS MAIL_PASSWORD=YOUR_GMAIL_SECRET MAIL_ENCRYPTION=tls |
Gmailの場合 『安全性の低いアプリの許可: 有効』にしないとMailを送れないため設定を行います。
Admin Login
これで一通りMulti AuthのAdminを作成できたと思います。
実際にログインできるか確かめるためにはTinkerを使います。
1 2 3 4 5 6 7 |
php artisan tinker $admin = new App\Admin $admin->name = "Admin" $admin->password = Hash::make('111111') $admin->role = "Admin" $admin->save() |
これで
111111
でログインできると思います。
是非試してみてください。
あとがき
今回はMulti Authを書きました。
超絶長くなってしまい本当に申し訳ないです。
かなり殴り書きになっているので誤字脱字あるかと思います。見つけ次第修正するようにします。
BlogとGithubで差異があった場合はGithubのファイルやコードが正しいと思ってください。
次回はSocial Loginです。
たぶんこんなには長くならないと思います。。
ここまで見ていただきありがとうございました。
コメントを残す