假设你已经定义了如下的路由
// Laravel
Route::get('orders/{orderId}, 'OrderController@show')
->where('orderId', '\d+');
// Lumen
$router->get('order/{orderId:\d+}, 'OrderController@show');
而且,控制器看起来像下面这样。
<?php namespace App\Http\Controllers;
// ...
class OrderController extends Controller
{
public function show(Request $request, $orderId) {
return Order::findOrFail($id);
}
}
所以,路由是直接的。这些URL将有一个代表orderId的整数id,这些将被传递给你的控制器。你使用该变量并执行操作。你可能会使用数据库表的自动增量id来从客户端到你的服务器进行通信,这是很常见的。
但是,假设你现在需要将这些orderId变量从整数改为你的新的超级加密值,这样就没有人能猜到订单ID。
所以,你需要将端点从 \d+ 更新为其他东西,如果它们不再是整数的话。即使它们是一个整数,它们也不能像以前那样发挥作用了。它们不再是表的主键ID了。所以,你可以考虑将控制器的orderId变量改成适合新加密密钥的新变量。
错了! 为什么?
假设你有10条路线有这个$orderId。现在,你需要在所有这些地方进行修改。
要偷懒!!!。用不同的方式思考。
又来了! 中间件可以成为救世主。因此,你需要做的是创建一个中间件,它将采取这些加密的参数,将其转换为实际的订单ID,并将其传递给控制器。
对于Laravel, 你可以做以下事情.
// EncryptedToRegularOrderIdMiddleware.php
...
public function handle($request, Closure $next) {
$encryptedOrderId = $request->route('orderId');
$request->route()->setParameter('orderId', (new Decoder())->decode($encryptedOrderId));
}
现在在你的控制器中,你不需要改变任何东西。你的控制器将不需要更新,因为你改变了路由参数。你需要注册中间件,并将这些应用于你的路由。
Route::get('orders/{orderId}, [
'uses' => 'OrderController@show',
'middleware' => 'encryption_to_regular', // registered MW name.
])->where('orderId', '\d+');
为什么你用粗体字提到Laravel?
因为在你的中间件中,在Laravel中$request->route()返回Illuminate/Routing/Route对象。在Lumen中,这是不一样的,它返回一个数组。所以,你不能只是在那里设置路由参数。你会得到一个异常。要做到这一点,你需要给你的$request对象注册一个路由解析器,这是一个闭包。所以,Lumen中的中间件类看起来像下面这样。
// EncryptedToRegularOrderIdMiddleware.php
...
public function handle($request, Closure $next) {
$route = $request->route();
if (isset($route[2]['orderId'])) {
$route[2]['orderId'] = (new Decoder())->decode($orderId);
$request->setRouteResolver(function () use ($route) {
return $route;
});
}
}
在Lumen中,$request->route()返回一个数组,其中数组key[2]持有将被传递到控制器的参数。你可以像Laravel那样修改这个值,最后用ingsetRouteResolver注册一个闭包。现在,这个解析器将在传递数据给你的控制器时使用。很简单。
That’s it. Be lazy. Happy coding!
本人也是找了好久才找到的这篇文章,感谢原作者,本文是直接机器翻译国外文章,希望能给到大家帮助!!!