استفاده از multi auth در لاراول

حمید تیموری 1900 بازدید 1398/05/20
استفاده از multi auth در لاراول

سیستم احراز هویت به صورت پیش فرض از جدول users استفاده میکند، اما اگر بخواهید از جدول admin استفاده کنید چطور؟

در هر وبسایت، ممکن است نقش های متعددی وجود داشته باشد به عنوان مثال نقش کاربر و ادمین و ... !
میتوانید با استفاده از سطوح دسترسی و gate و policy و ... این نقش ها را تفکیک کنید، و به عنوان مثال، برای هر نقش یک صفحه برای ورود به سایت بنویسید یا اینکه هنگام ورود، نوع کاربر را به صورت لیست نمایش دهید که کاربر آنها را انتخاب کند.

ولی اگر بخواهیم کاربر و ادمین سایت، در جداول جداگانه ای ذخیره شوند، چه کاری باید انجام دهیم ؟
برای اینکار باید برای ادمین یک Guard تعریف کنیم.
با دستور زیر مدل و مایگریشین ادمین را بسازید:

php artisan make:model Admin -m

حالا مایگریشن ساخته شده را ویرایش کنید، به عنوان مثال :

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateAdminsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('admins', function (Blueprint $table) {
            $table->increments('id'); 
            $table->string('name')->nullable();
            $table->string('family')->nullable(); 
            $table->string('email')->nullable();
            $table->boolean('activated')->default(0);
            $table->timestamp('activated_at')->nullable();
            $table->string('password',256)->nullable();
            $table->rememberToken();
            $table->softDeletes();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('admins');
    }
}

حالا مدل Admin را باز کنید

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class Admin extends Authenticatable
{
        use Notifiable;

        protected $guard = 'admin';

        protected $fillable = [
            'name', 'email', 'password',
        ];

        protected $hidden = [
            'password', 'remember_token',
        ];
}

دقت کنید که مدل شما به جای extend کردن از Model باید از Authenticatable ارث بری کند.
با این کار، شما میتوانید گارد پیش فرض را در مدل تعریف کنید

protected $guard = 'admin';

حالا اما باید guard را تعریف کنیم 
به مسیر زیر بروید:
config/auth.php

<?php

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'admin' => [                      # add this guard
            'driver' => 'session',
            'provider' => 'admins',
        ],

        'api' => [
            'driver' => 'jwt',
            'provider' => 'users',
        ],
    ],

حالا باید provider را هم برای گارد admin تعریف کنیم.
منظور از provider این است که این هر گارد، از کدام model استفاده کند.

'providers' => [
   [...]
   'admins' => [
     'driver' => 'eloquent',
     'model' => App\Admin::class,
   ],
   
],

همه چیز آماده است برای استفاده از guard در پروژه اما باید middleware هم برای این guard تعریف شود.
چند راه وجود دارد که این کار را انجام دهید.

برای اینکه تمرینی باشد برای ساخت middleware ، برای گارد admin، جداگانه middelware تعریف میکنیم که بتوانیم کاملا آنها را شخصی سازی کنیم:
شما میتوانید برای route ها یک middleware جداگانه بنویسید و از آن استفاده کنید. برای اینکار فرض کنید که یک folder به نام Admin در مسیر زیر دارید:

app/Http/Middelwares/Admin

این کار به مرتب تر شدن فایل های شما کمک میکند.
حالا با دستورهای زیر middleware های مورد نیاز را میسازیم.

php artisan make:middleware Admin\CheckIfAuthenticated

...

php artisan make:middleware Admin\RedirectIfAuthenticated

حالا باید middleware ها را در app\Http\Middleware تعریف کنیم.
فایل Kernel را باز کنید و در قسمت routeMiddleware به شکل زیر middleware ها را تعریف کنید

protected $routeMiddleware = [

  // ...

  'guest.admin' => \App\Http\Middleware\Admin\RedirectIfAuthenticated::class,
  'auth.admin' => \App\Http\Middleware\Admin\CheckIfAuthenticated::class,

];


(دقت کنید که روش های دیگری هم وجود دارد که همگی درست هستند !)

حالا CheckIfAuthenticated را ببینید که وظیفه اش نمایش صفحه ورود به پنل مدیریت است برای زمانی که فرد هنوز لاگین نکرده است.
تعریف صفحه لاگین و route برای پنل مدیریت مثل دیگر route ها است که به راحتی میتوانید این کار را انجام دهید.
( برای پنل مدیریت میتوانید جداگانه یک فایل route تعریف کنید )
در این مقاله ما فرض را بر این میگیریم که صفحه لاگین از قبل تعریف شده است.

<?php

namespace App\Http\Middleware\Admin;

use Closure;

class CheckIfAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
       
        if (!auth('admin')->check()) {
            return redirect()->route('admin.auth.login_form'); # admin login form
        }
        return $next($request);
    }
}

و همچنین RedirectIfAuthenticated که وظیفه دارد زمانی که فرد در پنل لاگین کرده، و دوباره url صفحه لاگین را وارد میکند، فرد به صفحه ای دیگر هدایت کنید، چون زمانی که فرد لاگین کرده است، نیازی نیست دوباره صفحه ی ورود به پنل را ببیند.

<?php

namespace App\Http\Middleware\Admin;

use Closure;

class RedirectIfAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        
        if (auth('admin')->check()) {
            return redirect()->route('admin.home.index'); # admin dashboard
        }

        return $next($request);
    }
}

حالا چطوری باید از middleware ها استفاده کنید ؟

فایل route را باز کنید:

Route::group(['middleware' => 'auth.admin'], function () {

  // routes are here ...

});

میبینید که تمامی route های admin را میتوانید به این محافظت کنید.

و اگر برای ورود به پنل مدیریت یک LoginController تعریف کرده اید، میتوانید به شکل زیر از middleware دیگری که تعریف کردیم، استفاده کنید.

 public function __construct()
 {
     $this->middleware('guest.admin')->except('logout');
 }


برای متد خروج هم به شکل زیر میتوانید استفاده کنید که در واقع باید ابتدا گارد مورد نظر را انتخاب کنید و سپس logout را صدا بزنید:

public function logout(Request $request)
{
    auth('admin')->logout();

    // do something ...
}


اگر به توضیح بیشتر نیاز بود، کامنت بذارید که مقاله رو بیشتر توضیح بدم .

دیگر مقالات
حمید تیموری 1076 بازدید 1397/05/20
حمید تیموری 775 بازدید 1398/10/01
امید کیانی 625 بازدید 1398/02/02
حمید تیموری 1138 بازدید 1397/12/04
حمید تیموری 973 بازدید 1397/04/18


نظرات (4)
مجید حیدری
1399/01/29 - 19:29
متود لاگ اوت برای این اتنتکیشنی که نوشتیم ، پیش فرض موجوده یا باید مجدد براش بنویسیم؟
حمید تیموری
1399/01/29 - 21:01
جواب سوالتون رو به آخر مقاله اضافه کردم
majid karami
1398/06/28 - 19:58
سلام من در این قسمت مقدار false رو دریافت میکنم
if (Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password], $request->get('remember'))) {

return redirect()->intended('/admin');
}
حمید تیموری
1398/06/29 - 21:56
درود، من تو این کد خطایی نمیبینم، دو تا قضیه رو دقت کنید، یکی اینکه رمز عبوری که وارد میکنید درست باشه، دوم اینکه گاردی که تعریف کردید درست باشه ممکنه admins تعریف کرده باشید ولی شما دارید از admin استفاده میکنید
برای ثبت نظر ابتدا وارد سایت شوید