چه طور در لاراول چند احراز هویت داشته باشیم!

Laravel Multi Auth
Laravel Multi Auth

اگر مدتی از لاراول استفاده کرده باشید ، حتما در مورد احراز هویت لاراول چیزهای زیادی را شنیده اید. در اين پست می خواهیم در مورد احراز هویت چند گانه لاراول صحبت کنیم. احراز هویت چندگانه باعث می شود کلاس های مختلف کاربران، دسترسی به قسمتهای مختلف یا مشابه یک برنامه مشابه را داشته باشند.

دلایل زیادی وجود دارد که شما ممکن است بخواهید از چندین احراز هویت در برنامه Laravel خود استفاده کنید. به عنوان مثال ، شما یک برنامه بزرگ دارید که کل یک شرکت را اداره می کند. مشتریان همچنین از طریق همین برنامه با محصول و خدمات شرکت ارتباط برقرار می کنند. همچنین این نرم افزار دارای یک وبلاگ است و یک بخش در شرکت وجود دارد که مسئولیت رسیدگی به وبلاگ را بر عهده دارد. در این شرکت بازاریاب هایی مشغول به کار هستند و از همین نرم افزار استفاده میکنند.سطح دسترسی در این برنامه باید متفاوت باشد.

از برنامه بالا مشاهده می کنیم که در حال حاضر 4 مجموعه کاربر وجود دارد. برای مشتریان ، ما می توانیم از آنها بخواهیم که برای دسترسی به سیستم از یک فرآیند تأیید خاص استفاده کنند. برای نویسندگان ، آنها می توانند یک پروسه احراز هویت کاملاً متفاوت و حتی محتوایی داشته باشند تا بتوانند یک روند مدیریت محتوا قوی تر داشته باشند. برای بازاریاب ها یک فرآیند احراز هویت جدا وجود دارد و برای بقیه شرکت ، شما می توانید نقش های مختلفی داشته باشید که عملکردهای مختلف را نشان می دهد.

حال ، به چگونگی ایجاد احراز هویت چندگانه برای طبقه مختلف کاربران خود می پردازیم.

شروع

ما یک برنامه Laravel ایجاد خواهیم کرد که دارای 4 کلاس کاربر است - مدیر ، نویسنده ، بازاریاب، مشتری. ما برای 4 کلاس کاربر guard درست می کنیم و قسمت های مختلف برنامه خود را بر اساس آن دسته از guard ها محدود می کنیم.

ما باید یک برنامه جدید Laravel ایجاد کنیم. دستور زیر را در ترمینال خود اجرا کنید تا یک برنامه جدید Laravel ایجاد کنید (ایجاد این پروژه با استفاده از Laravel installer انجام میشود شما میتوانید با composer هم این پروژه را ایجاد کنید):

  • laravel new multi-auth - - auth
  • cd multi-auth

ایجاد پایگاه داده

ما برای این پروژه از پایگاه داده My SQL استفاده خواهیم کرد. فایل env. پروژه خود را باز کنید و نام پایگاه داده را انتخاب کنید. برای مثال من نام پایگاه داده را multi-auth انتخاب میکنم.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=multi-auth
DB_USERNAME=root
DB_PASSWORD=

سپس در phpMyAdmin خود یک پایگاه داده خالی با نام multi-auth ایجاد کنید تا جدول های مربوط به پروژه به وسیله migration ها در آن ایجاد شوند.

در پستی که قبلا منتشر کرده ام، به طور کامل در مورد migration ها صحبت کرده ام. اگر هنوز آن را مطالعه نکرده اید، می توانید برای فهم بیشتر در مورد Migration ها به آن مراجعه کنید. (مبحث Migration ها در Laravel)

در این پروژه migration هایی برای جدول مدیران، نویسندگان و بازاریاب ها خواهیم نوشت. جدول آنها به اندازه جدول مشتری ها ساده خواهد بود ، اما شما می توانید آنها را بر اساس نیازهای خاص خود، آنها را گسترش دهید. توجه داشته باشید که جدول مشتری ها با استفاده از auth - - در ابتدا ی ایجاد پروژه، ایجاد شده است.

ایجاد جدول برای مدیران(Admins)

برای ایجاد migration برای تولید جدول admins، دستور زیر را در خط فرمان خود وارد کنید.

  • php artisan make:migration create_admins_table

با اجرای این دستور فایل migration مربوط به جدول admins در مسیر database/migrations ایجاد میشود. به آن پوشه رفته و فایل مربوطه را این طور تغییر دهید:

// database/migrations/<timestamp>_create_admins_table.php
[...]
public function up(){
    Schema::create('admins', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->boolean('is_super')->default(false);
        $table->rememberToken();
        $table->timestamps();
    });
}
[...]

با کد های بالا ما یک migration برای ایجاد جدول admins نوشتیم که با استفاده از متد های Eloquent نوع ستون های جدول را تعیین کردیم.

برای کاربران دیگر هم همانند "Admins" عمل میکنیم.

ایجاد جدول برای نویسندگان(Writers)

برای ایجاد migration برای تولید جدول writers، دستور زیر را در خط فرمان خود وارد کنید.

  • php artisan make:migration create_writers_table

با اجرای این دستور فایل migration مربوط به جدول writers در مسیر database/migrations ایجاد میشود. به آن پوشه رفته و فایل مربوطه را این طور تغییر دهید:

// database/migrations/<timestamp>_create_writers_table.php
[...]
public function up(){
    Schema::create('writers', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->boolean('is_editor')->default(false);
        $table->rememberToken();
        $table->timestamps();
    });
}
[...]

ایجاد جدول برای بازاریاب ها(Marketers)

برای ایجاد migration برای تولید جدول marketers، دستور زیر را در خط فرمان خود وارد کنید.

  • php artisan make:migration create_marketers_table

با اجرای این دستور فایل migration مربوط به جدول marketers در مسیر database/migrations ایجاد میشود. به آن پوشه رفته و فایل مربوطه را این طور تغییر دهید:

// database/migrations/<timestamp>_create_marketers_table.php
[...]
public function up(){
    Schema::create('marketers', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->boolean('is_super)->default(false);
        $table->rememberToken();
        $table->timestamps();
    });
}
[...]

حال migration های نوشته شده را با استفاده از دستور زیر اجرا کنید:

  • php artisan migrate

حال جدول هایی که اطلاعات آن را در migration ها نوشتیم در پایگاه داده multi-auth ایجاد شد. شما میتوانید این جدول ها را در phpMyAdmin خود ببینید.

تنظیمات مدل ها(Models)

ما کلاسهای مختلفی از کاربران برای برنامه خود داریم و آنها از جداول پایگاه داده مختلف استفاده می کنند. برای استفاده از این جداول مختلف برای احرازهویت ، باید مدل هایی را برای آنها تعریف کنیم. این مدل ها مانند مدل User خواهند بود و خاصیت های کلاس Authenticable را به ارث میبرند.

مدل Admin

برای ساختن مدل برای مدیر ، دستور زیر را اجرا کنید:

  • php artisan make:model Admin

فایل Admin.php را از پوشه App باز کنید و همانند کد های زیر آن را تغییر دهید:

// app/Admin.php
<?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', ];
}

هنگامی که شما قصد استفاده از مدلی را برای احراز هویت دارید و قصد دارید از guard پیش فرض user استفاده نکنید ، مهم است که guard مورد استفاده خود را تعیین کنید. در این مورد ما از admin guard استفاده می کنیم.

در ادامه در مورد guard ها بیشتر توضیح داده خواهد شد .

ما همچنین با قرار دادن آنها در آرایه قابل پر کردن(fiilable) برخی از ستون های پایگاه داده خود را به عنوان fillable تعریف کردیم. این به لاراول در مورد مدل زیر می گوید: اگر من متد ایجاد(create) یا به روزرسانی(update) را فراخوانی کرده و آرایه ای به عنوان آرگمان فرستادم، فقط ستون هایی که قابلیت fillable را دارند را قبول کن.

به این ترتیب ، از سناریویی جلوگیری خواهیم کرد که اگر کاربر بتواند از هر کدام از مرزهای امنیتی ما دور بماند و رکورد مورد نظر خود را برای درج یا به روزرسانی آنها بفرستد، اجازه این کار را نداشته باشد.

برای آرایه hidden ، ما به لاراول می گوییم وقتی مدل را به API یا نمای خود برگردانید ، این ستون ها را بازنگرداند.

برای کاربران دیگر همانند Admin عمل میکنیم.

مدل Writer

برای ساختن مدل برای نویسنده ، دستور زیر را اجرا کنید:

  • php artisan make:model Writer

فایل Writer.php را از پوشه App باز کنید و همانند کد های زیر آن را تغییر دهید:

// app/Writer.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Writer extends Authenticatable{
    use Notifiable;
    protected $guard = 'writer';
    protected $fillable = [ 'name', 'email', 'password', ];
    protected $hidden = [ 'password', 'remember_token', ];
}

مدل Marketer

برای ساختن مدل برای بازاریاب ، دستور زیر را اجرا کنید:

  • php artisan make:model Marketer

فایل Marketer.php را از پوشه App باز کنید و همانند کد های زیر آن را تغییر دهید:

// app/Marketer.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Marketer extends Authenticatable{
    use Notifiable;
    protected $guard = 'marketer';
    protected $fillable = [ 'name', 'email', 'password', ];
    protected $hidden = [ 'password', 'remember_token', ];
}

تعریف Guardها

نحوه احراز هویت کاربران برای هر درخواست را در لاراول، guard ها تعریف می كنند. لاراول برای احراز هویت برخی از guard ها را به طور پیش فرض دارد، اما ما می توانیم خودمان را نیز guard جدید ایجاد کنیم. این به ما این امکان را می دهد تا از سیستم احراز هویت پیش فرض Laravel با مدل های Admin و Writer و Marketer نیز استفاده کنیم.

فایل config/auth.php را باز کرده و guard های جدید خود را همانند کد های زیر به ان وارد کنید.

// config/auth.php
<?php
[...]
'guards' => [
    [...]
    'admin' => [
        'driver' => 'session',
        'provider' => 'admins',
    ],
    'writer' => [
        'driver' => 'session',
        'provider' => 'writers',
    ],
    'marketer' => [ 
        'driver' => 'session',
        'provider' => 'marketers',     ],
],
[...]

ما سه guard جدید مدیر و نویسنده و بازاریاب را اضافه کردیم و provider آنها را تنظیم کردیم. این provider به لاراول می گویند وقتی سعی می کنیم از guard ها استفاده کنیم ، برای احراز هویت یا اعتبار سنجی از چه چیزی استفاده کند.

اکنون موارد زیر را به لیست provider ها اضافه کنید:

// config/auth.php
[...]
'providers' => [
    [...]
    'admins' => [
        'driver' => 'eloquent',
        'model' => App\Admin::class,
    ],
    'writers' => [
        'driver' => 'eloquent',
        'model' => App\Writer::class,
    ],
    'marketers' => [
         'driver' => 'eloquent',  
         'model' => App\Marketer::class,     ],
],
[...]

اکنون ، ما provider های تعریف شده را به همراه guard های فوق تنظیم کرده ایم. ما driver را eloquent قرار داده ایم زیرا از Eloquent ORM به عنوان مدیر پایگاه داده ما استفاده می کنیم.

تنظیمات کنترلر ها(controllers)

برای استفاده از guard های خود برای احراز هویت، می توانیم کنترلرهای احراز هویت موجود را اصلاح کنیم یا موارد جدیدی ایجاد کنیم. شما می توانید بر اساس نیازهای خاص خود انتخاب کنید که استفاده کنید. در این آموزش این کنترلرها را اصلاح خواهیم کرد.

اصلاح LoginController

فایل LoginController در app/Http/Controllers/Auth را باز کرده و این گونه تغییر دهید:

// app/Http/Controllers/Auth/LoginController.php
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
[...]
use Illuminate\Http\Request;
use Auth;
[...]
class LoginController extends Controller{
    [...]
    public function __construct(){
        $this->middleware('guest')->except('logout');
        $this->middleware('guest:admin')->except('logout');
        $this->middleware('guest:writer')->except('logout');
        $this->middleware('guest:marketer')->except('logout');   
    }
    [...]
}

ما middleware را برای محدود کردن دسترسی به این کنترلر یا متد های آن تنظیم کردیم. مهم است که ما انواع مختلف guest را در کنترلر تعریف کنیم. به این ترتیب ، اگر یک نوع کاربر به سیستم وارد شوید و سعی کنید از یک کاربر دیگر برای ورود به سیستم استفاده کنید ، شما را به یک صفحه احراز هویت از پیش تعریف شده هدایت می کند. برای مثال اگر من به عنوان نویسنده وارد سیستم شوم، دیگر قادر نخواهم بود همزمان به عنوان مدیر نیز وارد سیستم بشوم.

در پستی که قبلا منتشر کرده ام، به طور کامل در مورد middleware ها صحبت کرده ام. اگر هنوز آن را مطالعه نکرده اید، می توانید برای فهم بیشتر در مورد Middleware ها به آن مراجعه کنید. (مبحث Middleware ها در Laravel)

حال برای مدیر پنل ورود ایجاد کنید:

 // app/Http/Controllers/Auth/LoginController.php
[...]
public function showAdminLoginForm(){
    return view('auth.login', ['url' => 'admin']);
}
public function adminLogin(Request $request){
    $this->validate($request, [
        'email' => 'required|email',
        'password' => 'required|min:6'
    ]);
    if (Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password], $request->get('remember'))) {
        return redirect()->intended('/admin');
    }
    return back()->withInput($request->only('email', 'remember'));
    }
[...]

ما متدی را برای بازگشت صفحه ورود به سیستم برای Admin تنظیم کرده ایم. برای همه ی انواع کاربر از همان صفحه استفاده خواهیم کرد و فقط آدرس اینترنتی ارسال شده (URL) را تغییر می دهیم. این کار باعث می شود از نوشتن کد های تکراری جلوگیری کنیم.

ما همچنین متد adminLogin را تعریف می کنیم که ابتدا بررسی می کند که فیلد های مربوطه اعتبار داشته باشند. برای این قسمت شما میتوانید اعتبارنامه شخصی ایجاد کرده و پیام های متناسب با آن ها را خودتان مشخص کنید(برای مثال در این جا حداقل طول رمز عبور 6 می باشد شما میتوانید این عدد را تغییر دهید). سپس سعی می کنیم کاربر را با guard مدیر (َAdmin) وارد سیستم کنیم. مهم این است که هنگام تلاش برای ورود به سیستم ، این guard را تنظیم کنیم تا Auth اعتبارنامه مطابق جدول مناسب را بررسی کند. همچنین تأیید اعتبار ما را تنظیم می کند ، بنابراین می توانیم صفحات را بر اساس نوع کاربری که وارد آن شده است محدود کنیم.

ما یک کاربر معتبر را به یک URL خاص هدایت می کنیم و یک کاربر غیرمجاز را به صفحه ورود ارسال می کنیم.

همین کار را برای ورود نویسنده و بازاریاب تکرار میکنیم.
// app/Http/Controllers/Auth/LoginController.php
[...]
public function showWriterLoginForm(){
    return view('auth.login', ['url' => 'writer']);
}
public function writerLogin(Request $request){
    $this->validate($request, [
         'email' => 'required|email',
         'password' => 'required|min:6'
    ]);
    if (Auth::guard('writer')->attempt(['email' => $request->email,  'password' => $request->password],  $request->get('remember'))) {
         return redirect()->intended('/writer');
     }
     return back()->withInput($request->only('email', 'remember'));
    }
[...]
public function showMarketerLoginForm(){     
    return view('auth.login', ['url' => 'marketer']); 
} 
public function marketerLogin(Request $request){    
     $this->validate($request, [ 
                              'email' => 'required|email', 
                              'password' => 'required|min:6'
     ]); 
    if (Auth::guard('marketer')->attempt(['email' => $request->email,  'password' => $request->password],  $request->get('remember'))) {                                                           
         return redirect()->intended('/marketer');                                                             
     }          
     return back()->withInput($request->only('email', 'remember'));
}
 [...]

اصلاح RegisterController

فایل RegisterController در app/Http/Controllers/Auth را باز کرده و این گونه تغییر دهید:

// app/Http/Controllers/Auth/RegisterController.php
<?php
[...]
namespace App\Http\Controllers\Auth;
use App\User;
use App\Admin;
use App\Writer;
use App\Marketer;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Http\Request;
[...]
class RegisterController extends Controller{
[...]
    public function __construct(){
        $this->middleware('guest');
        $this->middleware('guest:admin');
        $this->middleware('guest:writer');
        $this->middleware('guest:marketer');
    }
    [...]
}

در سازنده این کلاس، middleware های مربوط را تنظیم نمودیم ، دقیقاً مانند آنچه که با LoginController انجام دادیم.

اکنون متد هایی برای بازگشت صفحات ثبت نام برای کاربران مختلف را تنظیم می کنیم:

// app/Http/Controllers/Auth/RegisterController.php
[...]
public function showAdminRegisterForm(){
    return view('auth.register', ['url' => 'admin']);
}
public function showWriterRegisterForm(){
    return view('auth.register', ['url' => 'writer']);
}
public function showWriterRegisterForm(){
    return view('auth.register', ['url' => 'marketer']);
}
[...]

این مشابه کاری است که ما برای نمایش صفحات مختلف ورود به سیستم انجام داده ایم.

اکنون می توانیم متد های خود را برای ایجاد یک مدیر تعریف کنیم:

// app/Http/Controllers/Auth/RegisterController.php
[...]
protected function createAdmin(Request $request){
    $this->validator($request->all())->validate();
    $admin = Admin::create([
                                  'name' => $request['name'],
                                  'email' => $request['email'],
                                  'password' => Hash::make($request['password']),
    ]);
    return redirect()->intended('login/admin');
}
[...]

سپس متد های ایجاد نویسنده و بازاریاب را مشابه متد بالا ایجاد میکنیم:

// app/Http/Controllers/Auth/RegisterController.php
[...]
protected function createWriter(Request $request){
    $this->validator($request->all())->validate();
    $writer = Writer::create([
                                'name' => $request['name'],
                                'email' => $request['email'],
                                'password' => Hash::make($request['password']),
    ]);
    return redirect()->intended('login/writer');
}
[...]
protected function createMarketer(Request $request){
    $this->validator($request->all())->validate(); 
    $marketer = Marketer::create([ 
                                'name' => $request['name'], 
                                'email' => $request['email'], 
                                'password' => Hash::make($request['password']), 
    ]); 
    return redirect()->intended('login/marketer'); 
} 
[...]

تنظیمات صفحات احراز هویت

در ابتدای توضیحات، در قسمت ایجاد پروژه از دستور

  • laravel new multi-auth - - auth

برای ایجاد پروژه استفاده کردیم. در این دستور قسمت auth- - صفحات مربوط به احراز هویت و همچنین کنترلر های مربوط را ساخت و ما در قسمت های قبل برای احراز هویت چندگانه، کنترلر های مربوط را اصلاح کردیم. حال صفحات مربوط به احراز هویت موجود در resources/views/auth را اصلاح میکنیم.

برای ورود 4 گروه کاربر از یک صفحه مشترک با URL های متفاوت استفاده میکنیم. برای این کار فایل login.blade.php را این گونه اصلاح کنید:

// resources/views/auth/login.blade.php
[...]
<div class=&quotcard-header&quot> {{ isset($url) ? ucwords($url) : &quot&quot}} {{ __('Login') }}</div>
<div class=&quotcard-body&quot>
@isset($url)
    <form method=&quotPOST&quot action='{{ url(&quotlogin/$url&quot) }}' aria-label=&quot{{ __('Login') }}&quot>
@else
    <form method=&quotPOST&quot action=&quot{{ route('login') }}&quot aria-label=&quot{{ __('Login') }}&quot>
@endisset
@csrf
[...]
</div>
[...]

در حال بررسی این نکته هستیم که وقتی یک پارامتر url را به صفحه منتقل کردیم، عمل فرم را برای استفاده از پارامتر url اصلاح کنیم. همچنین عنوان فرم را طوری تغییر دادیم که نوع کاربر را بر اساس پارامتر ورود، به سیستم خود نشان می دهد.

برای ثبت نام 4 گروه کاربر از یک صفحه مشترک با URL های متفاوت استفاده میکنیم. برای این کار فایل register.blade.php را این گونه اصلاح کنید:

// resources/views/auth/register.blade.php
[...]
<div class=&quotcard-header&quot> {{ isset($url) ? ucwords($url) : &quot&quot}} {{ __('Register') }}</div>
<div class=&quotcard-body&quot>
@isset($url)
    <form method=&quotPOST&quot action='{{ url(&quotregister/$url&quot) }}' aria-label=&quot{{ __('Register') }}&quot>
@else
    <form method=&quotPOST&quot action=&quot{{ route('register') }}&quot aria-label=&quot{{ __('Register') }}&quot>
@endisset
@csrf
[...]
</div>
[...]

در این قسمت نیز همانند صفحه ورود عمل کردیم.

البته این نکته را نیز در نظر بگیرید که در عمل درست نیست که مدیر سیستم خود در سیستم ثبت نام کند. برای امنیت بیشتر ثبت نام مدیر توسط مدیر دیگر یا از ابتدا توسط seed های سیستم انجام می گیرد. برای ثبت نام مدیر توسط مدیر دیگر کافیست یک کنترلر برای مدیر سیستم (AdminController) ساخته و متد های مربوط به ایجاد مدیر جدید و نمایش فرم ثبت نام آن را به AdminController منتقل کنید و middleware ها را برای مدیر تنظیم کنید(('middleware('auth:admin). و مسیر دهی ها را که در ادامه به آن ها اشاره میشود را به پنل مدیر سیستم منتقل کنید.

ساخت پنل مخصوص 4 دسته از کاربران برای بعد از احراز هویت

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

  • $ touch resources/views/layouts/auth.blade.php
  • $ touch resources/views/admin.blade.php
  • $ touch resources/views/writer.blade.php
  • $ touch resources/views/marketer.blade.php
  • $ touch resources/views/home.blade.php

این کد را در فایل auth.blade.php قرار دهید:

// resources/views/layouts/auth.blade.php
<!DOCTYPE html>
<html lang=&quot{{ str_replace('_', '-', app()->getLocale()) }}&quot>
    <head>
        <meta charset=&quotutf-8&quot>
        <meta http-equiv=&quotX-UA-Compatible&quot content=&quotIE=edge&quot>
        <meta name=&quotviewport&quot content=&quotwidth=device-width, initial-scale=1&quot>
        <!-- CSRF Token -->
        <meta name=&quotcsrf-token&quot content=&quot{{ csrf_token() }}&quot>
        <title>{{ config('app.name', 'Laravel') }}</title>
        <!-- Scripts -->
        <script src=&quot{{ asset('js/app.js') }}&quot defer>
        <!-- Fonts -->
        <link rel=&quotdns-prefetch&quot href=&quothttps://fonts.gstatic.com&quot>
       <link href=&quothttps://fonts.googleapis.com/css?family=Raleway:300,400,600&quot rel=&quotstylesheet&quot type=&quottext/css&quot>
       <!-- Styles -->
       <link href=&quot{{ asset('css/app.css') }}&quot rel=&quotstylesheet&quot>
    </head>
    <body>
        <div id=&quotapp&quot>
            <nav class=&quotnavbar navbar-expand-md navbar-light navbar-laravel&quot>
            <div class=&quotcontainer&quot>
                <a class=&quotnavbar-brand&quot href=&quot{{ url('/') }}&quot>
                   {{ config('app.name', 'Laravel') }}
                </a>
               <button class=&quotnavbar-toggler&quot type=&quotbutton&quot data-toggle=&quotcollapse&quot data-target=&quot#navbarSupportedContent&quot aria-controls=&quotnavbarSupportedContent&quot aria- 
expanded=&quotfalse&quot aria-label=&quot{{ __('Toggle navigation') }}&quot>
                 <span class=&quotnavbar-toggler-icon&quot></span>
            </button>
            <div class=&quotcollapse navbar-collapse&quot id=&quotnavbarSupportedContent&quot>
                <!-- Left Side Of Navbar -->
                <ul class=&quotnavbar-nav mr-auto&quot></ul>
                <!-- Right Side Of Navbar -->
                <ul class=&quotnavbar-nav ml-auto&quot>
                <!-- Authentication Links -->
                <li class=&quotnav-item dropdown&quot>
               <a id=&quotnavbarDropdown&quot class=&quotnav-link dropdown-toggle&quot href=&quot#&quot role=&quotbutton&quot 
data-toggle=&quotdropdown&quot aria-haspopup=&quottrue&quot aria-expanded=&quotfalse&quot v-pre>
                     Hi There <span class=&quotcaret&quot></span>
                </a>
                <div class=&quotdropdown-menu dropdown-menu-right&quot aria-labelledby=&quotnavbarDropdown&quot>
                    <a class=&quotdropdown-item&quot href=&quot{{ route('logout') }}&quot
=&quotevent.preventDefault();
                     document.getElementById('logout-form').submit();&quot>
                       {{ __('Logout') }}
                    </a>
                   <form id=&quotlogout-form&quot action=&quot{{ route('logout') }}&quot method=&quotPOST&quot 
                            style=&quotdisplay: none;&quot>
                        @csrf
                   </form>
               </div>
              </li>
             </ul>
         </div>
     </div>
</nav>
<main class=&quotpy-4&quot>
     @yield('content')
</main>
</div>
</body>
</html>

حال پنل مدیران را طراحی کنید: admin.blade.php

// resources/views/admin.blade.php
@extends('layouts.auth')
@section('content')
    <div class=&quotcontainer&quot>
        <div class=&quotrow justify-content-center&quot>
            <div class=&quotcol-md-8&quot>
                <div class=&quotcard&quot>
                    <div class=&quotcard-header&quot>Admin Dashboard</div>
                   <div class=&quotcard-body&quot>Hi boss!</div>
                 </div>
             </div>
         </div>
    </div>
@endsection

حال پنل نویسندگان را طراحی کنید:writer.blade.php

// resources/views/writer.blade.php
@extends('layouts.auth')
@section('content')
    <div class=&quotcontainer&quot>
        <div class=&quotrow justify-content-center&quot>
            <div class=&quotcol-md-8&quot>
                <div class=&quotcard&quot>
                    <div class=&quotcard-header&quot>Writer Dashboard</div>
                   <div class=&quotcard-body&quot>Hi there, awesome writer!</div>
                 </div>
             </div>
         </div>
    </div>
@endsection

حال پنل بازاریاب ها را طراحی کنید:marketer.blade.php

// resources/views/marketer.blade.php
@extends('layouts.auth')
@section('content')
    <div class=&quotcontainer&quot>
        <div class=&quotrow justify-content-center&quot>
            <div class=&quotcol-md-8&quot>
                <div class=&quotcard&quot>
                    <div class=&quotcard-header&quot>Marketer Dashboard</div>
                   <div class=&quotcard-body&quot>Hi there, awesome marketer!</div>
                 </div>
             </div>
         </div>
    </div>
@endsection

حال پنل مشتری ها را طراحی کنید:home.blade.php (البته این فایل موجود است کافیست آن را اصلاح کنید.)

// resources/views/home.blade.php
@extends('layouts.auth')
@section('content')
    <div class=&quotcontainer&quot>
        <div class=&quotrow justify-content-center&quot>
            <div class=&quotcol-md-8&quot>
                <div class=&quotcard&quot>
                    <div class=&quotcard-header&quot>Dashboard</div>
                   <div class=&quotcard-body&quot>Hi there, regular user!</div>
                 </div>
             </div>
         </div>
    </div>
@endsection

تنظیمات مسیر ها

برنامه ما تقریباً آماده است حال مسیرهایی را برای دسترسی به تمام صفحاتی که تاکنون ایجاد کرده ایم تعریف می کنیم. فایل routes/web.php را باز کنید و موارد زیر را جایگزین کنید:

// routes/web.php
<?php
Route::view('/', 'welcome');
Auth::routes();
Route::get('/login/admin', 'Auth\LoginController@showAdminLoginForm');
Route::get('/login/writer', 'Auth\LoginController@showWriterLoginForm');
Route::get('/login/marketer', 'Auth\LoginController@showMarketerLoginForm');
Route::get('/register/admin', 'Auth\RegisterController@showAdminRegisterForm');
Route::get('/register/writer', 'Auth\RegisterController@showWriterRegisterForm');
Route::get('/register/marketer', 'Auth\RegisterController@showMarketerRegisterForm');
Route::post('/login/admin', 'Auth\LoginController@adminLogin');
Route::post('/login/writer', 'Auth\LoginController@writerLogin');
Route::post('/login/marketer', 'Auth\LoginController@marketerLogin');
Route::post('/register/admin', 'Auth\RegisterController@createAdmin');
Route::post('/register/writer', 'Auth\RegisterController@createWriter');
Route::post('/register/marketer', 'Auth\RegisterController@createMarketer');
Route::view('/home', 'home')->middleware('auth');
Route::view('/admin', 'admin');
Route::view('/writer', 'writer');
Route::view('/marketer', 'marketer);

در صورت احراز هویت ، نحوه هدایت کاربران باید اصلاح شود!

این مسئله مهم است که نحوه تغییر مسیر کاربران در هنگام احراز هویت را اصلاح کنید. Laravel به طور پیش فرض همه کاربران معتبر را به home/ هدایت می کند. اگر تغییر مسیر را تغییر ندهیم ، با خطا مواجه خواهیم شد. برای حل این خطا فایل app/Http/Controllers/Middleware/RedirectIfAuthenticated.php را اصلاح کنید.

// app/Http/Controllers/Middleware/RedirectIfAuthenticated.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated{
    public function handle($request, Closure $next, $guard = null){
        if ($guard == &quotadmin&quot && Auth::guard($guard)->check()) {
            return redirect('/admin');
        }
        if ($guard == &quotwriter&quot && Auth::guard($guard)->check()) {
            return redirect('/writer');
        }
        if ($guard == &quotmarketer&quot && Auth::guard($guard)->check()) { 
            return redirect('/marketer');  
        }
        if (Auth::guard($guard)->check()) {
            return redirect('/home');
        }
        return $next($request);
    }
}

میان افزار RedirectIfAuthenticated محافظ auth را به عنوان پارامتر دریافت می کند. این middleware هنگامی شروع می شود که می خواهیم از هر صفحه ای که برای کاربران معتبر قابل بازدید است، بازدید کنیم. سپس می توانیم نوع احراز هویت کاربر را تعیین کنیم و آنها را به ترتیب تغییر دهیم.

کنترل کننده استثناء احراز هویت را اصلاح کنید!

یک مورد آزار دهنده وجود دارد که هنگام هدایت کاربر اتفاق می افتد. شما انتظار دارید اگر مشتری سعی کند به writer/ دسترسی پیدا کند، اما تأیید نشده باشد ، به login/writer/ هدایت شود ، ولی این اتفاق نمی افتد. آنها به login/ سیستم هدایت می شوند که این چیزی نیست که ما می خواهیم.

برای اطمینان از اینکه وقتی مشتری سعی می کند از writer/ بازدید کند ، او به login/writer/ هدایت شود یا همین روال برای پنل های دیگر کاربران ، باید کنترل کننده استثنا را اصلاح کنیم. فایل app/Exceptions را باز کنید و موارد زیر را اضافه کنید:

// app/Exceptions/Handler.php
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
[...]
use Illuminate\Auth\AuthenticationException;
use Auth;
[...]
class Handler extends ExceptionHandler{
    [...]
    protected function unauthenticated($request, AuthenticationException $exception){
        if ($request->expectsJson()) {
            return response()->json(['error' => 'Unauthenticated.'], 401);
        }
       if ($request->is('admin') || $request->is('admin/*')) {
           return redirect()->guest('/login/admin');
       }
       if ($request->is('writer') || $request->is('writer/*')) {
           return redirect()->guest('/login/writer');
       }
      if ($request->is('marketer') || $request->is('marketer/*')) {  
          return redirect()->guest('/login/marketer'); 
       }
       return redirect()->guest(route('login'));
    }
}

برای استفاده از این استثنا باید به یک نکته توجه کنید! برای تمامی مسیر های مربوط به پنل هر یک از کاربران از ویژگی prefix استفاده کنید و اول مسیر guard مربوط به آن دسته از کاربر را وارد کنید. به این دلیل که در این استثنا بر اساس مسیر، guard را اعمال میکنیم.

اجرای پروژه

حال میتوانید با دستور

  • php artisan serve

پروژه خود را اجرا کرده و در آدرس http://localhost:8000مشاهده کنید.

مراجع : pusher.com