发布于 2026-01-06 0 阅读
0

请勿在URL中暴露数据库ID。

请勿在URL中暴露数据库ID。

在开发Web应用程序时,我们经常需要从数据库中获取信息。框架通过ORM(对象关系映射)简化了这一过程

大多数情况下,ORM 会使用主键作为可靠的标识符来查找您的模型。绝大多数情况下,主键都是自增整数。

您的网址将如下所示:



https://example.com/cart/12
https://example.com/user/15/post/41
...


Enter fullscreen mode Exit fullscreen mode

提供不正确或有缺陷的授权层可能会导致数据泄露:用户可以从一个数据跳转到另一个数据,如果涉及用户个人信息等敏感数据,我们绝不希望允许这种情况发生。

混淆标识符

缓解这种安全漏洞的一个简单方法是使用以下类型的密钥:

  • 难以预测
  • 随机性足以创造出大量物品,同时又能保持物品之间的独特性。
  • 可以轻松地从您的代码和数据库生成
  • 可验证的(我们可以通过分析其完整性来判断其是否有效)

感谢您的推荐,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


Enter fullscreen mode Exit fullscreen mode

Laravel 应用示例

为了练习开发Laravel包,并首次使用Github 工作流,我创建了一个包来简化这项工作。

以下是如何在您的应用程序中使用khalyomede/laravel-eloquent-uuid-slug 的方法。

安装软件包

首先,打开控制台,然后输入以下命令:



composer require khalyomede/laravel-eloquent-uuid-slug


Enter fullscreen mode Exit fullscreen mode

将你的 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
    });
  }
};


Enter fullscreen mode Exit fullscreen mode

将该特性添加到您的模型中

这是最后一步,它将帮助您配置如何使用路由模型绑定在路由中检索您的模型。



namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Khalyomede\EloquentUuidSlug\Sluggable;

final class Cart extends Model
{
  use Sluggable;
}


Enter fullscreen mode Exit fullscreen mode

在控制器中使用它

现在您就可以开始使用该软件包了。它的优点在于您的代码无需更改!您可以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");


Enter fullscreen mode Exit fullscreen mode

瞧!正如您所见,这个软件包不会干扰您现有的逻辑。唯一的变化是,您的路由现在不再暴露。



route("cart.show", $cart); // https://example.com/cart/398e76a7-7c16-467c-93a8-04c06c6df703


Enter fullscreen mode Exit fullscreen mode

结论

虽然这个解决方案并不能彻底解决数据泄露的根本问题,但我认为它是一种非常容易实施的机制,可以减少恶意用户欺骗系统的可能性。

但这并不妨碍您添加授权或防护机制,例如Laravel Policies。例如,如果用户访问的购物车并非由其本人创建,则不应允许其查看该购物车中的商品。

这里其他人已经讨论过这个话题了,所以如果你想了解更多关于使用 UUID 的信息,一定要去看看:

URL加固成功!

文章来源:https://dev.to/anwar_nairi/do-not-expose-database-ids-in-your-urls-567