请勿在URL中暴露数据库ID。
在开发Web应用程序时,我们经常需要从数据库中获取信息。框架通过ORM(对象关系映射)简化了这一过程。
大多数情况下,ORM 会使用主键作为可靠的标识符来查找您的模型。绝大多数情况下,主键都是自增整数。
您的网址将如下所示:
https://example.com/cart/12
https://example.com/user/15/post/41
...
提供不正确或有缺陷的授权层可能会导致数据泄露:用户可以从一个数据跳转到另一个数据,如果涉及用户个人信息等敏感数据,我们绝不希望允许这种情况发生。
混淆标识符
缓解这种安全漏洞的一个简单方法是使用以下类型的密钥:
- 难以预测
- 随机性足以创造出大量物品,同时又能保持物品之间的独特性。
- 可以轻松地从您的代码和数据库生成
- 可验证的(我们可以通过分析其完整性来判断其是否有效)
感谢您的推荐,UUID非常适合。它符合上述所有要求,并且由于有大量现成的软件包可供使用,因此非常易于使用。
现在您的 URL 将更难预测,从而减少开发人员在应用程序中授权策略方面可能出现的任何错误:
https://example.com/cart/f6e4208f-5df4-466e-9225-01f296e2a09c
https://example.com/user/b1b44b12-34bc-4ed7-a666-9657b8b8c31b/post/e530d034-42f7-467b-91e3-1cc9313312eb
Laravel 应用示例
为了练习开发Laravel包,并首次使用Github 工作流,我创建了一个包来简化这项工作。
以下是如何在您的应用程序中使用khalyomede/laravel-eloquent-uuid-slug 的方法。
安装软件包
首先,打开控制台,然后输入以下命令:
composer require khalyomede/laravel-eloquent-uuid-slug
将你的 slug 列添加到你的迁移文件中
然后,转到您选择的模型的迁移,或者如果已经安装了该模型,则创建一个新的模型,并添加 slug 列。
namespace Database\Migrations;
use App\Models\Cart;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
final class AddSlugColumnToCartTable extends Migration {
public function up(): void
{
Schema::table('carts', function (Blueprint $table): void {
Cart::addSlugColumn($table);
});
}
public function down(): void
{
Schema::table('carts', function (Blueprint $table): void {
Cart::dropSlugColumn($table); // available soon in v0.2.0
});
}
};
将该特性添加到您的模型中
这是最后一步,它将帮助您配置如何使用路由模型绑定在路由中检索您的模型。
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Khalyomede\EloquentUuidSlug\Sluggable;
final class Cart extends Model
{
use Sluggable;
}
在控制器中使用它
现在您就可以开始使用该软件包了。它的优点在于您的代码无需更改!您可以route()像以前一样继续使用该方法。
// routes/web.php
use App\Models\Cart;
use Illuminate\Http\RedirectResponse
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Illuminate\View\View;
Route::get("cart/{cart}", function (Cart $cart): View {
return view("cart.show", [
"cart" => $cart,
"saveCartRoute" => route("cart.store", $cart),
]);
})->name("cart.show");
Route::post("cart/{cart}", function (Request $request, Cart $cart): RedirectResponse {
$cart->update($request->only(["name"]));
return redirect()->route("cart.show", $cart);
})->name("cart.store");
瞧!正如您所见,这个软件包不会干扰您现有的逻辑。唯一的变化是,您的路由现在不再暴露。
route("cart.show", $cart); // https://example.com/cart/398e76a7-7c16-467c-93a8-04c06c6df703
结论
虽然这个解决方案并不能彻底解决数据泄露的根本问题,但我认为它是一种非常容易实施的机制,可以减少恶意用户欺骗系统的可能性。
但这并不妨碍您添加授权或防护机制,例如Laravel Policies。例如,如果用户访问的购物车并非由其本人创建,则不应允许其查看该购物车中的商品。
这里其他人已经讨论过这个话题了,所以如果你想了解更多关于使用 UUID 的信息,一定要去看看:
URL加固成功!
文章来源:https://dev.to/anwar_nairi/do-not-expose-database-ids-in-your-urls-567