php
這一節,咱們完成登陸登出的功能, 在路由中設置中間件, 過濾一些非法請求,關於中間件、用戶受權請參靠官方文檔,若是是新手,強烈建議先看下文檔而後再開始下面的工做。css
#知識學習:html
HTTP 中間件提供了一個方便的機制來過濾進入應用程序的 HTTP 請求,例如,Laravel 自己使用中間件來驗證用戶的身份,若是用戶未經過身份驗證,中間件將會把用戶導向登陸頁面,反之,當用戶經過了身份驗證,中間件將會經過此請求並接着往下執行。laravel
固然,除了身份驗證以外,中間件也能夠被用來運行各式各樣的任務,CORS 中間件負責替全部即將離開程序的響應加入適當的標頭。而日誌中間件則能夠記錄全部傳入應用程序的請求。git
Laravel 框架已經內置了一些中間件,包括維護、身份驗證、CSRF 保護,等等。全部的中間件都放在app/Http/Middleware
目錄內。ajax
如果但願每一個 HTTP 請求都通過一箇中間件,只要將中間件的類加入到 app/Http/Kernel.php
的 $middleware
屬性清單列表中。json
若是你要指派中間件給特定路由,你得先在 app/Http/Kernel.php
給中間件設置一個好記的鍵,默認狀況下,這個文件內的 $routeMiddleware
屬性已包含了 Laravel 目前設置的中間件,你只須要在清單列表中加上一組自定義的鍵便可。bootstrap
// 在 App\Http\Kernel 類內... protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,];
中間件一旦在 HTTP kernel 文件內被定義,便可在路由選項內使用 middleware 鍵值指定:數組
Route::get('admin/profile', ['middleware' => 'auth', function () { //}]);
項目實戰:app
先看routes.php的登錄登出的路由:
############## ### 登錄登出功能 ############## Route::get('login', [ // 'uses' :表示指定路由名稱到控制器動做 'middleware' => 'guest', 'as'=>'login', 'uses' => 'loginController@LoginGet' ]); Route::post('login', [ 'middleware' => 'guest', 'uses' => 'loginController@LoginPost' ]); Route::get('logout', [ 'middleware' => 'auth', 'as'=>'logout', 'uses' => 'loginController@Logout' ]);
guest 只容許遊客(沒登錄的狀況下)訪問get路由login和post路由login,要是已經登陸,就會跳轉到相應頁面,注意關鍵詞響應。咱們登陸用戶有兩種,學生,和管理員,當他們在登陸的狀況下要想訪問這兩個路由,確定會作出不一樣的響應。即,學生,跳轉到學生主頁,管理員,跳轉到管理員主頁.如今來看看RedirectIfAuthenticated.php
/** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { if ($this->auth->check()) // 用戶是否登錄 { if(!Auth::user()->is_admin){ return new RedirectResponse('/stu/home'); // 不是管理員 }else{ return new RedirectResponse(url('/admin')); // 若是是管理員,則進入後臺管理頁面 } } return $next($request); }
auth 只有登陸用戶才能訪問,auth是在Kernel.php中註冊的全局中間件
'auth' => \App\Http\Middleware\Authenticate::class,
咱們能夠看下源碼 Authenticate.php
/** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { if ($this->auth->guest()) // 沒有登陸,是遊客 { if ($request->ajax()) // 經過ajax來請求,這裏返回json數據 { return response('Unauthorized.', 401); } else // 直接請求, 跳轉到登陸頁 { return redirect()->guest('auth/login'); } } return $next($request); }
也就是說只有登陸了才能登出,就是這個意思。
說完了中間件,建立控制器。loginController.php
php artisan make:controller loginController --plain
在loginController.php的控制器中寫須要的方法:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use App\Http\Controllers\Controller; // 引入用戶類 use App\UsersInfo; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Redirect; class loginController extends Controller { /** * 返回login視圖,登錄頁面 */ public function loginGet() { return view('login'); } /** * 登錄響應 */ public function loginPost(Request $request) { // 登陸驗證規則 $this->validate($request, UsersInfo::rules()); $id = $request->get('id'); $password = $request->get('password'); if(Auth::attempt(['id' => $id, 'password' => $password], $request->get('remember'))) { if(!Auth::user()->is_admin){ return Redirect::route('stu_home'); }else { return Redirect::action('Admin\AdminController@index'); } }else{ return Redirect::route('login') ->withInput() ->withErrors('學號或者密碼不正確,請重試!'); } } /** * 用戶登出 */ public function logout() { if (Auth::check()) { Auth::logout(); } return Redirect::route('login'); } }
可使用validate驗證用戶輸入,在laravel5中使用validate很是方便,注意第二個參數,User::rules(), 這是在User模型中一個靜態方法,接着在User.php中加入靜態方法。
protected static function rules() { return [ 'id' => 'required|digits:10', <!-- 表明必需填寫,10位數字 --> 'password' => 'required' <!-- 必填 --> ]; }
驗證用戶登陸使用了Auth::attempt(),這是laravel中自帶的驗證方法,很是好用,若是驗證經過,接着判斷是不是管理員,而後分別跳轉到不一樣的url.
return Redirect::route('stu_home') -- 對應路由名爲stu_home的路由 return Redirect::action('Admin\AdminController@index') -- 對於這個index方法
登出使用的是Auth::logout().
這時候點擊登陸,laravel會告訴你view(login)不存在,建立login.blade.php文件
@extends('master') @section('title') 歡迎登陸 @stop @section('content') <div class="container-fluid"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="panel panel-default"> <div class="panel-heading">登陸</div> <div class="panel-body"> @include('errors.list') {!! Form::open(['url' => '/login', 'class' => 'form-horizontal', 'role' => 'form']) !!} <div class="form-group"> {!! Form::label('id', '學號', ['class' => 'col-md-4 control-label']) !!} <div class="col-md-6"> {!! Form::text('id', old('id'), ['class' => 'form-control', 'required']) !!} </div> </div> <div class="form-group"> {!! Form::label('password', '密碼', ['class' => 'col-md-4 control-label']) !!} <div class="col-md-6"> {!! Form::password('password', ['class' => 'form-control', 'required']) !!} </div> </div> <div class="form-group"> <div class="col-md-6 col-md-offset-4"> <div class="checkbox"> <label> <input type="checkbox" name="remember"> Remember Me </label> </div> </div> </div> <div class="form-group"> <div class="col-md-6 col-md-offset-4"> {!! Form::submit('Login', ['class' => 'btn btn-primary form-control']) !!} </div> </div> {!! Form::close() !!} </div> </div> </div> </div> </div> @stop
這時候要是點擊登陸,若是報錯,由於在laravel5中Illuminate/Html組件被移了,咱們能夠在composer.json的required數組中加入
"illuminate/html": "5.0"
在config/app.php中的provider數組中添加
'Illuminate\Html\HtmlServiceProvider',
aliases數組中添加
'Html' => 'Illuminate\Html\HtmlFacade', 'Form' => 'Illuminate\Html\FormFacade',
接着執行:
composer update
等待安裝完成以後,就能看到咱們的登陸頁面了
這時候你隨便輸入學號密碼,頁面會刷新一下,不會跳轉,錯誤已經被存在了Session中,如今把他顯示出來. 在login.blade.php中有這樣一行
@include('errors.list')
咱們建立errors/list.blade.php
@if (count($errors) > 0) <div class="alert alert-danger"> <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif
這時候要是輸入不符合前面的規則,你會看到提示英文提示信息,要是輸入密碼或者賬號錯誤,你會看到 學號或者密碼不正確,請重試, 這是loginPost中返回的自定義錯誤信息.
如今,咱們有兩個問題須要解決,第一,英文提示信息,對咱們中國用戶可能不太友好,你能夠更換.第二,錯誤提示會一直留着頁面.下面,咱們一一解決.
關於表單驗證的自定義錯誤信息,能夠查看官方連接, 如今咱們找到/resources/lang/en/validation.php,在custom數組中添加:
'id' => [ 'required' => '學號不能爲空', "digits" => "學號必須是 10 位數字", "unique" => "該同窗已經存在", ], 'password' => [ 'required' => '密碼不能爲空', ],
從新隨便輸入學號密碼,你就能夠看到中文提示信息了
關於提示信息的隱藏,這裏有兩種簡單的解決方案,參靠bootstrap中的警告框,修改/errors/list.blade.php
@if (count($errors) > 0) <div class="alert alert-danger alert-dismissible" role="alert"> <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button> <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif
這個時候錯誤信息的右邊就會有一個關閉按鈕,點擊就可隱藏錯誤信息
第二種帶關閉提示錯誤信息的顯示框: