Laravel系列之CMS系統學習 — 角色、權限配置【1】

1、後臺Admin模塊php

  後臺管理是有管理員的,甚至超級管理員,因此在設計數據表的時候,就會有2個方案,一個方案是共用users數據表,添加is_admin,is_superAdmin字段來進行驗證,或者將用戶編到不一樣的組裏面,另外一個方案是,單首創建admins數據表來進行管理(這樣前臺和後臺是兩個事件,前臺用戶是沒有機會操做後臺相關功能的,也就是徹底隔離了)laravel

  我採用第二種(實習快四個月了,跟了2個完整項目是這樣~)git

  我在上一篇說到,我使用的是laravel-module,因此相關初始配置再也不贅述。github

  使用artisan hd:module Admin後,可訪問後臺界面partTime.com/adminweb

2、動態分層管理後臺菜單設計模式

3、建立Guard守衛實現先後臺帳號分離api

  1. 守衛Guard配置session

    請仔細看下面代碼中的註釋~app

  1 <?php
  2 
  3 return [
  4 
  5     /*
  6     |--------------------------------------------------------------------------
  7     | Authentication Defaults
  8     |--------------------------------------------------------------------------
  9     |
 10     | This option controls the default authentication "guard" and password
 11     | reset options for your application. You may change these defaults
 12     | as required, but they're a perfect start for most applications.
 13     | defaults:默認使用web守衛者
 14     | guard:守衛者,守衛web(也就是前臺的全部操做)
 15     | passwords:守衛者對應的數據表,也便是根據哪一張來進行守衛
 16     |
 17     */
 18 
 19     'defaults' => [
 20         'guard'     => 'web',
 21         'passwords' => 'users',
 22     ],
 23 
 24     /*
 25     |--------------------------------------------------------------------------
 26     | Authentication Guards
 27     |--------------------------------------------------------------------------
 28     |
 29     | Next, you may define every authentication guard for your application.
 30     | Of course, a great default configuration has been defined for you
 31     | here which uses session storage and the Eloquent user provider.
 32     |
 33     | All authentication drivers have a user provider. This defines how the
 34     | users are actually retrieved out of your database or other storage
 35     | mechanisms used by this application to persist your user's data.
 36     |
 37     | Supported: "session", "token"
 38     | 這部分是定義守衛者
 39     | driver:經過什麼方式來檢索用戶,要麼session會話,要麼token令牌
 40     | provider:對應的數據表
 41     |
 42     */
 43 
 44     'guards' => [
 45         'web'   => [
 46             'driver'   => 'session',
 47             'provider' => 'users',
 48         ],
 49         'admin' => [
 50             'driver'   => 'session',
 51             'provider' => 'admins',
 52         ],
 53 
 54         'api' => [
 55             'driver'   => 'token',
 56             'provider' => 'users',
 57         ],
 58     ],
 59 
 60     /*
 61     |--------------------------------------------------------------------------
 62     | User Providers
 63     |--------------------------------------------------------------------------
 64     |
 65     | All authentication drivers have a user provider. This defines how the
 66     | users are actually retrieved out of your database or other storage
 67     | mechanisms used by this application to persist your user's data.
 68     |
 69     | If you have multiple user tables or models you may configure multiple
 70     | sources which represent each model / table. These sources may then
 71     | be assigned to any extra authentication guards you have defined.
 72     |
 73     | Supported: "database", "eloquent"
 74     | 由於Laravel對數據表的操做都是經過模型Model,因此須要再此定義
 75     | Admin模型定義:php artisan make:model Admin -fm(f表明模型工廠,m表明數據遷移表) 這種方式很方便,比用一個一個去建立了~~不使用此方法的話,萬一表定義錯了,你還得告訴模型你使用的是拿一張表
 76     |
 77     */
 78 
 79     'providers' => [
 80         'users'  => [
 81             'driver' => 'eloquent',
 82             'model'  => App\User::class,
 83         ],
 84         'admins' => [
 85             'driver' => 'eloquent',
 86             'model'  => App\Admin::class,
 87         ],
 88 
 89         // 'users' => [make
 90         //     'driver' => 'database',
 91         //     'table' => 'users',
 92         // ],
 93     ],
 94 
 95     /*
 96     |--------------------------------------------------------------------------
 97     | Resetting Passwords
 98     |--------------------------------------------------------------------------
 99     |
100     | You may specify multiple password reset configurations if you have more
101     | than one user table or model in the application and you want to have
102     | separate password reset settings based on the specific user types.
103     |
104     | The expire time is the number of minutes that the reset token should be
105     | considered valid. This security feature keeps tokens short-lived so
106     | they have less time to be guessed. You may change this as needed.
107     |
108     */
109 
110     'passwords' => [
111         'users' => [
112             'provider' => 'users',
113             'table'    => 'password_resets',
114             'expire'   => 60,
115         ],
116     ],
117 
118 ];
auth.php

   注意:less

    此時建立出來的Admin.php以下,實際上是不完整的喲,往下看~

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Admin extends Model
{
    //
}

  2. View、Controller的配置

    View可使用和前臺同樣的界面,也能夠本身修改界面,無非就是個樣式問題

    Controller和前臺同樣

    因此若是同樣的話,直接複製粘貼,修改控制器的namespace就好啦~

    若是你使用了不一樣UI,卻發現界面不對的話,在LoginController添加如下方法

// 這是指定顯示哪個界面
public function showLoginForm()
{
    return view('admin::auth.login');
}

 

  3. 路由配置

    方法一:

1 // middleware中間件
2 // prefix:前綴(可使用artisan route:list查看)好比:前臺登錄:http://parttime.com/login,後臺登錄:http://parttime.com/admin/login(其中的admin就是屬性prefix指定的)
3 Route::group(
4     ['middleware' => 'web', 'prefix' => 'admin', 'namespace' => 'Modules\Admin\Http\Controllers'],
5     function () {
6         Auth::routes();
7     }
8 );

   若是用這種方式的話,那麼form表單的action屬性就得寫成action="/admin/login"

  方法二:

 1 Route::group(
 2     ['middleware' => 'web', 'prefix' => 'admin', 'namespace' => 'Modules\Admin\Http\Controllers'],
 3     function () {
 4         Route::name('admin.')->group(
 5             function () {
 6                 Auth::routes();
 7             }
 8         );
 9     }
10 );

  若是用這種方式的話,那麼form表單的action屬性就得寫成action="{{route('admin.login')}}"

4. 錯誤

  錯誤一:郵箱不能爲空

    LoginController中use了一個AuthenticatesUsers,它裏面有那個方法username()是指定驗證的用戶名是誰,默認是email,咱們能夠對它進行重寫

public function username()
{
    return 'name';// 或者你想驗證的屬性
}

  錯誤二:用戶名密碼錯誤

   爲了方便測試,咱們將admins表中的第一條數據進行了修改,所以排除Factory、AdminSeeder的錯誤

   其實AuthenticatesUsers還有一個guard()方法,它指定使用哪個守衛者,不傳參默認使用web,因此須要對它進行重寫(也就是告訴網頁,此時的url是誰保護的)

protected function guard()
{
    return \Auth::guard('admin');
}

  錯誤三:好多英文~

    截至目前,Admin.php中只是繼承了Model,它只是實現了對錶的一些操做,好比增刪改查等等,並無守衛者

    那咱們來看一下系統默認的User.php模型是怎麼樣的

 1 <?php
 2 
 3 namespace App;
 4 
 5 use Illuminate\Notifications\Notifiable;
 6 use Illuminate\Foundation\Auth\User as Authenticatable;
 7 
 8 class User extends Authenticatable
 9 {
10     use Notifiable;
11 
12     /**
13      * The attributes that are mass assignable.
14      *
15      * @var array
16      */
17     protected $fillable = [
18         'name', 'email', 'password',
19     ];
20 
21     /**
22      * The attributes that should be hidden for arrays.
23      *
24      * @var array
25      */
26     protected $hidden = [
27         'password', 'remember_token',
28     ];
29 }
User.php

    咱們能夠模仿它來改造咱們的Admin.php模型

 1 <?php
 2 
 3 namespace App;
 4 
 5 use Illuminate\Notifications\Notifiable;
 6 use Illuminate\Foundation\Auth\User as Authenticatable;
 7 
 8 class Admin extends Authenticatable
 9 {
10     use Notifiable;
11     
12     //
13 }

    搞定,後臺也能夠登錄啦~ 而後你又會發現一個問題,爲啥跳轉到了前臺登錄界面

  錯誤四:跳轉錯誤

   其實這裏暗藏了兩個問題:1.爲何跳轉錯誤(確定是和後臺相關的一些配置出了問題)2.爲何跳轉到的是前臺的登錄界面

   我們先解決第2個問題:

     這是前臺路由配置,Laravel有中間件機制,當前臺用戶沒有登錄的時候,他訪問了網址,就會自動跳轉到登錄界面,而控制這個Controller是前臺的HomeController.php

 1 <?php
 2 
 3 /*
 4 |--------------------------------------------------------------------------
 5 | Web Routes
 6 |--------------------------------------------------------------------------
 7 |
 8 | Here is where you can register web routes for your application. These
 9 | routes are loaded by the RouteServiceProvider within a group which
10 | contains the "web" middleware group. Now create something great!
11 |
12 */
13 
14 // 主頁面
15 Route::get(
16     '/',
17     function () {
18         return view('welcome');
19     }
20 );
21 
22 // 前臺登錄、註冊、找回密碼
23 Auth::routes();
24 
25 Route::get('/home', 'HomeController@index')->name('home');
web.php
 1 <?php
 2 
 3 namespace App\Http\Controllers;
 4 
 5 class HomeController extends Controller
 6 {
 7     /**
 8      * Create a new controller instance.
 9      *
10      * @return void
11      */
12     public function __construct()
13     {
14         $this->middleware('auth');
15     }
16 
17     /**
18      * Show the application dashboard.
19      *
20      * @return \Illuminate\Http\Response
21      */
22     public function index()
23     {
24         return view('home');
25     }
26 }
HomeController.php

  再解決第一個問題:

    很簡單,再Admin模塊的LoginController.php中,有一個$redirectTo屬性就是控制跳轉的~

    補充:

      不管前臺仍是後臺,用戶登錄成功了之後,再經過地址欄訪問登錄界面是不該該出現它的,因此中間件的魅力就能夠凸顯~

4、中間件設置先後臺跳轉不一樣路由

  中間件有Laravel已經配置好的(app/Http/Kernel.php),也能夠本身自定義

  先後臺的LoginController.php的構造方法以下

1 public function __construct()
2 {
3     $this->middleware('guest')->except('logout');// except:指定的方法或方法組不進行驗證
4 }

    guest中間件是對遊客的限制,那麼就會有一個問題:如何指定這個有可能即將登錄的遊客是什麼角色呢,是前臺用戶,仍是後臺管理員?因此guard守衛者再次派上用場

    middleware('guest:admin')當不指定admin的時候默認採用web(前臺)守衛者,不然採用指定的守衛者(這裏是admin守衛者)

    那麼又產生一個問題:我驗證成功了,如何針對不一樣角色的用戶實現不一樣的跳轉呢?

    下面是guest中間件所對應的類實現的方法(暫時忽略$next,這個和設計模式有關,如今還用不到)

      邏輯很簡單,判斷是否有傳進來的守衛者,沒有就用默認的web,而後進行跳轉/home(問題就在這裏:無論前臺仍是後臺都是跳轉/home,顯然是不對的,所以須要對其進行修改)

 1 <?php
 2 
 3 namespace App\Http\Middleware;
 4 
 5 use Closure;
 6 use Illuminate\Support\Facades\Auth;
 7 
 8 class RedirectIfAuthenticated
 9 {
10     /**
11      * Handle an incoming request.
12      *
13      * @param  \Illuminate\Http\Request  $request
14      * @param  \Closure  $next
15      * @param  string|null  $guard
16      * @return mixed
17      */
18     public function handle($request, Closure $next, $guard = null)
19     {
20         if (Auth::guard($guard)->check()) {
21             return redirect('/home');
22         }
23 
24         return $next($request);
25     }
26 }

    修改後:

 1 <?php
 2 
 3 namespace App\Http\Middleware;
 4 
 5 use Closure;
 6 use Illuminate\Support\Facades\Auth;
 7 
 8 class RedirectIfAuthenticated
 9 {
10     /**
11      * Handle an incoming request.
12      *
13      * @param  \Illuminate\Http\Request $request
14      * @param  \Closure $next
15      * @param  string|null $guard
16      *
17      * @return mixed
18      */
19     public function handle($request, Closure $next, $guard = null)
20     {
21         if (Auth::guard($guard)->check()) {
22             // 能夠自行決定跳轉到哪裏~
23             return redirect($guard == 'admin' ? '/admin' : '/home');
24         }
25 
26         return $next($request);
27     }
28 }

  

AuthenticatesUsers
相關文章
相關標籤/搜索