寻找有关如何处理面向公众的对象id的建议

时间:2012-01-18 21:30:44

标签: php mysql

我需要帮助来提出一个策略来处理我正在研究的PHP / MySQL应用程序中的对象id。基本上,不是让URL看起来像这样:

/post/get/1

我正在寻找类似的东西:

/post/get/92Dga93jh

我知道通过默默无闻的安全性是无用的(我有一个ACL系统来处理安全性)但我仍然需要模糊ID。这就是我被困住的地方。

我考虑过为每个数据库行生成一个单独的公共ID,但却无法找到创建真正唯一ID的方法。

我想我可以加密和解密MySQL自动增量行ID,因为它离开并进入我的应用程序,但我不确定PHP的加密和解密方法是多么“昂贵”。此外,我需要确保隐藏的ID保持唯一,以便它不会解密为错误的值。

此外,由于我的域对象彼此相关,所以如果我决定在表中生成并存储一个模糊的id,我想避免对MySQL造成任何不必要的压力。

我正在撞墙,因为我觉得这是一种常见的情况,但却无法弄清楚该怎么做。非常感谢任何帮助!

5 个答案:

答案 0 :(得分:1)

只要你给出9-char base62字符串 - 你就可以遵循这个策略:

  1. 生成1到13537086546263552(62 ^ 9)
  2. 的数字
  3. 将其转换为base62字符串
  4. 尝试插入数据库(您应该在id字段上有唯一索引)
  5. 如果确定 - 什么都不做
  6. 如果不好 - 重复1-3

答案 1 :(得分:1)

使用像md5等单向哈希

答案 2 :(得分:1)

我只是使用盐渍的md5。 99%的案例都是安全的。另外1%将是当你在墙上歪歪扭扭而导致你的数据被专业黑客窃取时,最小化它的影响变得至关重要。

所以:

$sql = 'SELECT * FROM my_table WHERE MD5(CONCAT(ID, "mysupersalt")) = "'.$my_checked_url_value.'"';

从PHP生成相同的东西可以使用类似的策略来完成:

<a href="/link/to/mypage/<?php echo md5($id.'mysupersalt'); ?>"> link text </a>

希望这就是你要找的......

答案 3 :(得分:1)

真的取决于应用程序,如果超级必要的是你拥有用户永远无法“猜测”原始ID的ID,那么使用递归调用db来生成唯一的公共ID。

如果另一方面,如果有人可以“猜测”原始ID并且关注性能,你只需要ID看起来不同而没有任何安全担忧,你可以想出一个快速和基本的数学方程式在访问URL时,动态生成唯一ID并对其进行解码。

(我知道它是一个HACK,但在很多情况下完成了工作)

E.g。如果我访问/blog/id/x!1@23409235(表示/blog/id/1

在代码中,我可以通过以下方式解码:

$blogId = intval(substr($_GET['id'], 4)) - 23409234;

当然,在生成URL时,您将23409234添加到原始URL的id中,并使用一些随机char位作为前缀..

哦,您可以使用Apache的mod_rewrite进行所有这些计算。

答案 4 :(得分:0)

最简单的方法是检查

中是否有这样的记录
do {
    $id = generateID();
}
while(idExists($id)); 

环。不应该有很多重复的ID,因此在大多数情况下,大多数时候只有两个查询:检查和插入。

相关问题