Lumen HTTP 路由

2021-09-15 14:39 更新

1、基本路由

大部分路由都定義在bootstrap/app.php文件載入的app/Http/routes.php中。

最基本的Lumen路由接收一個URI和一個閉包:

$app->get('/', function () {
    return 'Hello World';
});

$app->post('foo/bar', function () {
    return 'Hello World';
});

$app->put('foo/bar', function () {
    //
});

$app->delete('foo/bar', function () {
    //
});

生成指向路由對應(yīng)的URL

可以使用幫助函數(shù)url來生成路由對應(yīng)的URL:

$url = url('foo');

2、路由參數(shù)

2.1 必選參數(shù)

有時我們需要在路由中捕獲URI片段,比如,如果想要從URL中捕獲用戶ID,可以通過如下方式定義路由參數(shù):

$app->get('user/{id}', function ($id) {
    return 'User '.$id;
});

可以按需要定義在路由中定義多個路由參數(shù):

$app->get('posts/{post}/comments/{comment}', function ($postId, $commentId) {
    //
});

路由參數(shù)總是通過花括號進行包裹,參數(shù)在路由被執(zhí)行時會被傳遞到路由的閉包。

注意:路由參數(shù)不能包含’-‘字符,需要的話可以使用_替代。

2.2 正則約束

可以通過在路由中定義定義正則表達式來約束路由參數(shù)格式:

$app->get('user/{name:[A-Za-z]+}', function ($name) {
    //
});

3、命名路由

命名路由使生成URL或者重定向到指定路由變得很方便,在定義路由時指定路由名稱,然后使用數(shù)組鍵as指定路由別名:

$app->get('user/profile', ['as' => 'profile', function () {
    //
}]);

還可以為控制器動作指定路由名稱:

$app->get('user/profile', [
    'as' => 'profile', 'uses' => 'UserController@showProfile'
]);

生成指向命名路由的URL

一旦你為給定路由分配了名字,通過route函數(shù)生成URL時就可以使用路由名字:

$url = route('profile');
$redirect = redirect()->route('profile');

如果路由定義了參數(shù),可以將路由參數(shù)作為第二個參數(shù)傳遞給route函數(shù)。給定的路由參數(shù)將會自動插入URL中:

$app->get('user/{id}/profile', ['as' => 'profile', function ($id) {
    //
}]);
$url = route('profile', ['id' => 1]);

4、路由分組

路由分組允許我們在多個路由中共享路由屬性,比如中間件命名空間等,這樣的話一大波共享屬性的路由就不必再各自定義這些屬性。共享屬性以數(shù)組的形式被作為第一個參數(shù)傳遞到$app->group方法中。

想要了解更多路由分組,我們希望通過幾個簡單的應(yīng)用實例來展示其特性。

4.1 中間件

要分配中間件給分組中的所有路由,可以在分組屬性數(shù)組中使用middleware鍵。中間件將會按照數(shù)組中定義的順序依次執(zhí)行:

$app->group(['middleware' => 'auth'], function () {
    $app->get('/', function ()    {
        // 使用 Auth 中間件
    });

    $app->get('user/profile', function () {
        // 使用 Auth 中間件
    });
});

4.2 命名空間

另一個通用的例子是路由分組分配同一個PHP命名空間給多個控制器,可以在分組屬性數(shù)組中使用namespace參數(shù)來指定分組中控制器的命名空間:

$app->group(['namespace' => 'Admin'], function(){
    // 控制器在 "App\Http\Controllers\Admin" 命名空間下

    $app->group(['namespace' => 'User'], function()
    {
        // 控制器在 "App\Http\Controllers\Admin\User" 命名空間下
    });
});

默認情況下,RouteServiceProvider包含routes.php并指定其所在命名空間為App\Http\Controllers,因此,我們只需要指定App\Http\Controllers之后的相對命名空間即可。

4.3 路由前綴

屬性prefix可以用來為分組中每個給定URI添加一個前綴,比如,你想要為所有路由URI前面添加前綴admin

$app->group(['prefix' => 'admin'], function () {
    $app->get('users', function ()    {
        // 匹配 "/admin/users" URL
    });
});

你還可以使用prefix參數(shù)為分組路由指定公共參數(shù):

$app->group(['prefix' => 'accounts/{account_id}'], function () {
    $app->get('detail', function ($account_id)    {
        // 匹配 accounts/{account_id}/detail URL
    });
});

5、CSRF攻擊及保護

注意:使用Lumen的該特性之前必須開啟session。

5.1 簡介

Lumen使得防止應(yīng)用遭到跨站請求偽造攻擊變得簡單??缯菊埱髠卧焓且环N通過偽裝授權(quán)用戶的請求來利用授信網(wǎng)站的惡意漏洞。

Lumen自動為每一個被應(yīng)用管理的有效用戶Session生成一個CSRF“令牌”,該令牌用于驗證授權(quán)用戶和發(fā)起請求者是否是同一個人。想要生成包含CSRF令牌的隱藏輸入字段,可以使用幫助函數(shù)csrf_field來實現(xiàn):

<?php echo csrf_field(); ?>

幫助函數(shù)csrf_field生成如下HTML:

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">

當然還可以使用Blade模板引擎提供的方式:

{!! csrf_field() !!}

你不需要了解在POST、PUT或者DELETE請求時CSRF令牌是如何進行驗證的,HTTP中間件VerifyCsrfToken會為我們做這項工作:將請求中輸入的token值和session中的存儲的作對比。

5.2 X-CSRF-Token

除了將CSRF令牌作為一個POST參數(shù)進行檢查,Lumen的VerifyCsrfToken中間件還會檢查X-CSRF-TOKEN請求頭,你可以將令牌保存在”meta”標簽中:

<meta name="csrf-token" content="{{ csrf_token() }}">

創(chuàng)建完這個meta標簽后,就可以在js庫如jQuery中添加該令牌到所有請求頭,這為基于AJAX的應(yīng)用提供了簡單、方便的方式來避免CSRF攻擊:

$.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
});

5.3 X-XSRF-Token

Lumen還將CSRF令牌保存到了名為XSRF-TOKEN的cookie中,你可以使用該cookie值來設(shè)置X-XSRF-TOKEN請求頭。一些JavaScript框架,比如Angular,將會為你自動進行設(shè)置,基本上你不太會手動設(shè)置這個值。

6、表單方法偽造

HTML表單不支持PUT、PATCH或者DELETE動作,因此,當定義被HTML表單調(diào)用的PUTPATCHDELETE路由時,需要添加一個隱藏的_method字段到給表單中,其值被用作HTTP請求方法名:

<form action="/foo/bar" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>

7、拋出404錯誤

有兩者方法手動從路由觸發(fā)404錯誤。

第一種,使用幫助函數(shù)abort,abort函數(shù)會拋出一個指定狀態(tài)碼的Symfony\Component\HttpFoundation\Exception\HttpException

abort(404);

第二種,手動拋出Symfony\Component\HttpKernel\Exception\NotFoundHttpException.的實例。

更多關(guān)于處理404異常的信息以及如何自定義視圖顯示這些錯誤信息,請查看錯誤文檔一節(jié)。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號