【问题标题】:Using Primary Key / ID Field as an identifier in a URL使用主键/ID 字段作为 URL 中的标识符
【发布时间】:2010-10-08 16:41:27
【问题描述】:

使用数据库主键作为 URL 标识符的优缺点是什么?例如,http://localhost/post/view/13 - 13 是我的帖子表的主键。

像 reddit 之类的一些网站使用我假设的唯一 ID,它不是主键但仍然是唯一的,以帮助识别链接:

http://www.reddit.com/r/funny/cmets/7ynin/the_mystery_of_irelands_worst_driver/

只要 /7ynin/ 相同,您可以将 URL 的最后一部分更改为您想要的任何内容。


Digg 似乎使用链接标题的 slug 来标识链接:

http://digg.com/space/Liquid_Water_Recently_Seen_on_Mars

如果我没记错的话,默认的 WordPress 安装使用 index.php?p=# 作为他们的 id,直到启用花哨的 url。


我明白为什么为了 SEO 的缘故,您可能希望获得信息量最大的 url,但我只是想看看使用主键是否存在安全风险,或者仅仅是错误的形式。

【问题讨论】:

  • 向上看,向上看。你看到了什么?一个主键。加上一个对 SEO 友好的蛞蝓。如果你有一个友好的名字,请使用一个友好的名字,否则一个 PK 很好。但请确保用户看不到其他用户信息。

标签: security database-design friendly-url


【解决方案1】:

Reddit 也使用数字 ID,但使用 Base 36 转换,因此它显示为字符串。这就像十六进制数,实际上也是一个字符串。唯一的区别是基础。

Base 36 是“使用 ASCII 字符的最紧凑、不区分大小写的字母数字系统”,它易于编码和解码。为什么是36? A-Z = 26 + 0-9 = 10。

【讨论】:

    【解决方案2】:

    您总是希望向用户呈现一个漂亮的 URL,而不是一些讨厌的自动生成的 ID。但我认为您不应该将所说的“友好 url”作为主键。您仍然应该使用“经典”自动递增的数字 PK,并有第二列是唯一的“友好 url”。为什么?

    1. 所有评论表、评分 桌子,任何有 与内容表的关系 可以使用数字主键。 这意味着更小的索引和更低的 内存使用。
    2. 有人会想要 更改友好的网址。如果你有 有一个数字主键,你没有 必须更新您的任何受抚养人 表(或让数据库通过 级联更新)。
    3. 未来, 您可以抽象出 URL 位 到另一张桌子。所述表可以 然后存储“旧版”URL 映射 该问题重定向到主要 “真实”的 URL 映射。那么当用户 想要更改友好的 URL, 你不必打破所有 入站旧版 URL。做不到 如果您的主键是 “友好的网址”。
    4. 我仍然倾向于在我的所有 AJAX goo 中使用数字主键(例如,post_new_comment() javascript 函数将采用主键,而不是一些友好的 URL)。我唯一一次使用友好 URL 是在任何面向用户的 URL 结构中。
    5. 至于安全?如果您的内容受访问控制,则无论它是主键还是某个友好 URL,您都必须检查访问权限。
    6. 如果您允许通过主键访问内容,人们可能会尝试插入随机 ID。如果您不仅要求限制对内容的访问,而且拒绝所述内容存在,那是您的错误措辞的问题。这与登录失败是一样的——你没有说“找不到用户名”,而是说“用户名或密码错误”。插入随机值来查找内容对于您采用的任何方法都是一个问题,只是使用数字键可以尝试的值更少。

    底线:友好的 URL?地狱是的。使用它们作为主键?见鬼。

    【讨论】:

      【解决方案3】:

      如果您在 URL/链接中包含主键,那么您必须制作某种临时合成键,然后,您必须保存映射用户会话中的那个键。这会增加更多的状态/内存使用/破坏您的应用程序的东西。

      如果该值真的很敏感,那么可能值得付出隐藏它的代价。但是,隐藏密钥并不能真正使其安全,不是吗?在授予对项目的访问权限之前,您需要检查任何“控制器”(servlet、代码隐藏等)中的用户角色。

      【讨论】:

        【解决方案4】:

        正如您所说,将标题直接放在 URL 中的目的是 SEO。 URL 中包含关键字对搜索引擎结果有显着影响。

        但是,与您的示例相关的其他一些想法:

        • 我不确定您为什么认为 reddit 字母数字键不是主键,没有什么可以强制主键为数字键。如果它是帖子的唯一标识符,则没有理由不将其用作主键(或至少是其中的一部分)。
        • Digg 实际上强制标题的唯一性(也许只是在特定类别中,我已经好几年没去过 Digg,所以我不记得了)。我以前经常看到这样的重复故事,其 URL 如下:

          http://digg.com/space/Liquid_Water_Recently_Seen_on_Mars_2
          

          这意味着标题至少是主键的一部分,因为这是识别链接打算指向哪个故事的唯一方法。

        正如 pantulis 所提到的,除了人们猜测/预测其他主键的能力之外,在 URL 中使用主键并没有任何重大的安全风险。但无论如何,您不应该依赖“没人会猜到这一点”作为安全措施。

        【讨论】:

        • 非常好的点。我想我对什么构成主键的想法有点错误。我喜欢 digg 网址的简洁性,但允许在 reddit 的 url 中重复 slug 的能力。我想我会尝试将两者结合使用。谢谢!
        【解决方案5】:

        虽然它确实告诉外部实体有关您的系统的信息,但它本质上不是安全风险,这通常是避免的好习惯。

        【讨论】:

        • 我牺牲?我想如果我使用相关的关键字,我会推广 SEO。也许我只是看错了。
        • 在那个编辑中(我放弃了,因为我写的时候没有阅读你问题的最后一段),我的意思是如果你使用主键而不是 slug,你会牺牲 SEO 价值。 (如果除了 slug 之外还使用它们,也会牺牲 SEO 价值,但不会那么多。)
        【解决方案6】:

        一个缺点:任何访问者都可以轻松尝试并猜测其他 ID,这可能不是您想要的。

        【讨论】:

        • 在大多数情况下,我真的看不出使用 URL 中的不同 ID 访问网站上的内容有什么问题。如果您谈论的是个人用户页面和应该受到限制的内容,您应该已经有其他身份验证方法来防止访问。
        猜你喜欢
        • 2011-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-20
        • 1970-01-01
        • 2022-01-22
        相关资源
        最近更新 更多