HTTP 路由

未匹配的标注
本文档最新版为 6.x,旧版本可能放弃维护,推荐阅读最新版!

HTTP 路由

基本路由

你可以在 app/Http/routes.php 文件中定义应用程序的大多数路由,该文件将会被 bootstrap/app.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 () {
    //
});

生成 URLs 路由

你可以通过 url 辅助函数生成应用程序路由:

$url = url('foo');

路由参数

基础路由参数

有时候你可能需要在你的 URI 路由中来获取一些参数。例如,从 URL 获取用户的 ID。这时可通过自定义路由参数来获取:

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

你可以依照路由需要,定义任意数量的路由参数:

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

路由的参数都会被放在「大括号」内。当运行路由时,参数会通过路由闭包来传递。

注意:路由参数不能包含 - 字符。请用下划线 (_) 替换。

正则表达式限制参数

你可以在路由实例上使用 where 方法来限制路由参数格式。where 方法接受参数的名称和定义参数应该如何被限制的正则表达式:

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

命名路由

命名路由让你可以更方便的为特定路由生成 URL 或进行重定向。你可以使用 as 数组键指定名称到路由上:

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

还可以指定路由名称到控制器动作:

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

对命名路由生成 URLs

一旦你在指定的路由中分配了名称,则可通过 route 函数来使用路由名称生成 URLs 或重定位:

$url = route('profile');

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

如果路由定义了参数,那么你可以把参数作为第二个参数传递给 route 方法。指定的参数将自动加入到 URL 中:

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

$url = route('profile', ['id' => 1]);

路由群组

路由群组允许你共用路由属性,例如:中间件、命名空间,你可以利用路由群组到多个路由中套用这些属性,而不需在每个路由上都设置一次。共用属性被指定为数组格式,当作 $app->group 方法的第一个参数。

为了了解更多路由群组的相关内容,我们可通过几个常用样例来熟悉这些特性。

中间件

要想指定中间件到所有群组内的路由中,则可以在群组属性数组里使用 middleware 参数。中间件将会依照列表内指定的顺序运行:

$app->group(['middleware' => 'auth'], function ($app) {
    $app->get('/', function ()  {
        // Uses Auth Middleware
    });

    $app->get('user/profile', function () {
        // Uses Auth Middleware
    });
});

命名空间

另一个常见的例子是,指定相同的 PHP 命名空间给控制器群组。可以使用 namespace 参数来指定群组内所有控制器的命名空间:

$app->group(['namespace' => 'App\Http\Controllers\Admin'], function ($app) {

    // Controllers Within The "App\Http\Controllers\Admin" Namespace

});

路由前缀

通过路由群组数组属性中的 prefix,在路由群组内为每个路由指定的 URI 加上前缀。例如,你可能想要在路由群组中将所有的路由 URIs 加上前缀 admin

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

你也可以使用 prefix 参数去指定路由群组中共用的参数:

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

CSRF 保护

注意: 你必须开启 会话 才能使用此功能。

介绍

Lumen 提供简单的方法保护你的应用程序不受到 跨网站请求伪造 攻击。跨网站请求伪造是一种恶意的攻击,借以通过身份验证的用户身份来运行未经授权的命令。

Lumen 会自动生成一个 CSRF token 给每个受应用程序管理的活动用户的 Session。该 token 用来验证用户是否为实际发出请求的用户。若要生成一个包含 CSRF token 的 _token 隐藏输入字段,可以使用 csrf_field 辅助函数:

<?php echo csrf_token(); ?>

csrf_field 辅助函数生成以下的 HTML:

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

你不需要手动验证 POST、PUT 或 DELETE 请求的 CSRF token。在 VerifyCsrfToken HTTP 中间件 将自动验证请求与 session 中的 token 是否相符。

X-CSRF-TOKEN

除了检查 CSRF token 是否被当作 POST 参数之外,在 Lumen VerifyCsrfToken 中间件也会检查请求标头中的 X-CSRF-TOKEN。例如,你可以将其保存在 meta 标签中:

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

一旦你创建了 meta 标签,你就可以使用 jQuery 之类的函数库将 token 加入到所有的请求标头。基于 AJAX 的应用,提供了简单、方便的 CSRF 保护:

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

X-XSRF-TOKEN

Lumen 也会在 XSRF-TOKEN cookie 中保存 CSRF token。你也可以使用 cookie 的值来设置 X-XSRF-TOKEN 请求标头。一些 JavaScript 框架会自动帮你处理,例如:Angular。你不大可能会需要手动去设置这个值。

跨站请求伪造

HTML 表单没有支持 PUTPATCHDELETE 动作。所以在从 HTML 表单中调用被定义的 PUTPATCHDELETE 路由时,你将需要在表单中增加隐藏的 _method 字段。跟随 _method 字段送出的值将被作为 HTTP 的请求方法使用:

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

抛出 404 错误

这里有两种方法来从路由手动触发 404 错误。首先,你可以使用 abort 辅助函数。abort 辅助函数只是简单的抛出一个带有指定状态代码的 Symfony\Component\HttpFoundation\Exception\HttpException

abort(404);

其次,你也可以手动抛出 Symfony\Component\HttpKernel\Exception\NotFoundHttpException 的实例。

更多有关如何操作 404 异常和自定义响应,可以到 错误 章节内参考文档。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~