laravel 學習筆記——路由(中間件與路由組)


本文包含以下小節,在閱讀之前建議大致閱讀官方文檔。

  • 中間件
  • 路由組

 

中間件

在官方文檔上,這一部分是在路由的后面,但我想把它挪到前面來,這樣更為合理。

這是什么呢?

我們知道,路由是一個過程,分析來自客戶端的請求按照路由規則分發至相應的處理邏輯。但有種情況,打個比方:后台。后台不是所有人都能訪問的,我們在正式的處理邏輯前,需要做一個驗證,比如驗證是否具有權限或者請求的數據是否合法。

這時候,路由過程的一部分——中間件就上場了。

HTTP 中間件提供一個方便的機制來過濾進入應用程序的 HTTP 請求,例如,Laravel 默認包含了一個中間件來檢驗用戶身份驗證,如果用戶沒有經過身份驗證,中間件會將用戶導向登錄頁面,然而,如果用戶通過身份驗證,中間件將會允許這個請求進一步繼續前進。

上述內容來自中文版的 laravel 5 文檔,里面很好的說明了中間件的作用。在 laravel 5 以前的版本,只有過濾器(路由篩選器),目的和現在的中間件一樣都是在請求到處理邏輯之間的一個中間過程,一般用作前置和后置的判斷、驗證。通過中間件我們可以在控制器里專注其本身的邏輯,就好比一個后台的控制器,我只需要專注於顯示用戶列表或者文章列表、去處理添加的文章等等,而不需要關注訪問者是否是合法的后台管理員,驗證權限的工作,應該交由中間件。通過中間件驗證就會正常處理,不通過就會被重定向或者其他操作。

Laravel默認已經內置了許多中間件,且默認開啟。可以通過編輯app/Http/Kernel.php來決定是否啟用這些中間件。自己開發的中間件也是在這里進行注冊的哦。

app/Http/Kernel.php 中的 $middleware 數組是全局中間件,也就是說,任何一條路由都會被應用這些中間件,比如里面的CSRF驗證中間件。

有時候我們不需要全局中間件,這時候可以將某一個中間件注冊至 app/Http/Kernel.php文件中的 $routeMiddleware 數組,數組的鍵名是中間件的別名,鍵值是具體的中間件類,如

'auth' => 'App\Http\Middleware\AuthMiddleware'。

具體如何在某一路由上使用特定的中間件我們下文繼續。

我們在 app/Http/Kernel.php 文件中的 $routeMiddleware 數組注冊了一個獨立中間件,這一中間件可被單獨用綁定在一個路由和路由組上。在路由定義的時候可以像這樣:

  1. Route::get('admin/profile',['middleware'=>'auth',function()
  2. {
  3. //
  4. }]);

當我們訪問 http://yourdomain/admin/profile 的時候,首先會經過全局中間件,然后就是我們在 app/Http/Kernel.php 的 $routeMiddleware 數組中定義的名稱為 auth 的中間件。

說了這么多關於如何定義,那么中間件類里面應該是什么樣的呢?看過文檔的應該知道是這樣的(下面的代碼和文檔里的有些區別哦):

  1. <?php
  2. namespaceApp\Http\Middleware;
  3.  
  4. useClosure;
  5. useAuth;
  6.  
  7. classAuthMiddleware{
  8.  
  9. /**
  10. * Run the request filter.
  11. *
  12. * @param \Illuminate\Http\Request $request
  13. * @param \Closure $next
  14. * @return mixed
  15. */
  16. publicfunction handle($request,Closure $next)
  17. {
  18. // If the user is not logged in
  19. if(Auth::guest()){
  20. if($request->ajax()){
  21. return response('Unauthorized!',401);
  22. }else{
  23. return redirect()->guest('admin/login');
  24. }
  25. }
  26.  
  27. view()->share('loign',true);
  28. return $next($request);
  29. }
  30.  
  31. }

上面這段代碼是已經寫好了的中間件,handle 方法里面的內容就是中間件實際的代碼。

我們看得出第 18~27 行代碼大概是一個判斷用戶是否登陸的過程,如果沒有登錄,則判斷請求是否是 ajax 類型的,ajax 類型的請求就返回一個表示“你丫的沒權限”的 json 數據(理解一下就行),如果是標准的請求就重定向至登陸界面。

如果在中間件中,通過了你的驗證、或者前置的操作邏輯,記得通過代碼 return $next($request)(上述例子中28行)將請求導向下一個中間件,如果后面沒有中間件,就會到的處理邏輯(比如控制器等)。

上述中間件是一個前置操作的中間件,什么意思呢?就是在作用在實際處理邏輯前的中間件,就是一個前置中間件。相反,當一個實際處理邏輯運行完以后通過的中間件,就是一個后置中間件。

后置中間件結構如下:

  1. <?php
  2. namespaceApp\Http\Middleware;
  3.  
  4. classAfterMiddlewareimplementsMiddleware{
  5.  
  6. publicfunction handle($request,Closure $next)
  7. {
  8. $response = $next($request);
  9.  
  10. // 具體的中間件邏輯代碼
  11.  
  12. return $response;
  13. }
  14. }

我們看得出,區別在於多了個 $response = $next($request),返回值也變了。很好理解,$next($request) 返回的值是整個請求經過無數具體處理邏輯后產生的最終響應,這個響應一般是一堆 html 代碼(渲染后的視圖),也可能是一個 json 等等。我們可以在中間件里面對這個響應做最后加工處理,最后返回處理完的結果。

路由組群

這一塊官方文檔有着十分詳盡的描述,但是似乎不太容易理解。先說說適用場景。

路由組群往往適用於給某一類路由分組,給這個路由組分配的中間件、過濾器等,都會被運用到該組內的所有路由。

說白了,路由組就是簡化一部分路由定義過程的。比如,后台的我都想通過地址http://yourdomain/admin/*** 訪問,假如我有 用戶(user)文章(article) 兩個模塊,他們的訪問都要經過一個驗證權限的中間件,我需要這樣定義路由:

  1. Route::get('admin/user',['middleware'=>'authority',function(){
  2. // blablabla...
  3. }]);
  4.  
  5. Route::get('admin/article',['middleware'=>'authority',function(){
  6. // blablabla...
  7. }]);

現在只有兩條路由,我多寫幾個 admin,middleware 沒啥的,但系統龐大以后,每個都要單獨寫對應的中間件,容易出錯,不易管理。這時候,就應該使用路由組:

  1. Route::group(['prefix'=>'admin','middleware'=>'authority'],function(){
  2. Route::get('user',function(){
  3. // blablabla...
  4. });
  5. Route::get('article',function(){
  6. // blablabla...
  7. });
  8. });

同時,利用路由組,定義子域名變得十分容易:

  1. Route::group(['domain'=>'bbs.yourdomain.com'],function(){
  2. Route::get('topic',function(){
  3. // blablabla...
  4. });
  5.  
  6. Route::get('node',function(){
  7. // blablabla...
  8. });
  9. });

子域名也可以擁有通配符,以此實現更為靈活的結構。比如我希望我的網站每一個用戶都擁有自己的二級域名,類似於這樣:userA.yourdomain.com,userB.yourdomain.com。這時候可以這樣寫:

  1. Route::group(['domain'=>'{username}.myapp.com'],function()
  2. {
  3. Route::get('profile/{type}',function($username, $type)
  4. {
  5. //
  6. });
  7. });

可以通過參數獲取域名上的通配符匹配的值。

除這些以外,路由組帶來的便利相當豐富,在這里基本把路由組存在的意義說完了,其他關於路由組的可以移步至官方文檔了解。

轉載:https://www.insp.top/article/learn-laravel-middleware-routegroup


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM