使用主键/ID 字段作为 URL 中的标识符

发布于 2024-07-14 15:12:30 字数 628 浏览 8 评论 0原文

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

像 reddit 这样的一些网站使用我认为是唯一的 id,它不是主键,但仍然是唯一的,以帮助识别链接:

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

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


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

http://digg.com/space/Liquid_Water_Recently_Seen_on_Mars

如果我没记错的话,默认的 WordPress 安装会使用 index.php?p=# 作为其 id,直到启用奇特的 url。


我可以理解为什么为了 SEO 的缘故,您可能希望拥有信息最丰富的 url,但我只是想看看使用主键是否存在安全风险,或者只是一种不好的形式。

What are the pros and cons of using your databases primary key as a URL identifier? As an example, http://localhost/post/view/13 - 13 being my primary key for my posts table.

Some sites like reddit use what I assume is a unique id that is not the primary key but still unique to help identify the link:

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

You can change the last part of the URL to whatever you want as long as the /7ynin/ is the same.


Digg seems to use a slug of the links title to id a link:

http://digg.com/space/Liquid_Water_Recently_Seen_on_Mars

While if i recall correctly a default WordPress install uses index.php?p=# as their id until fancy urls are enabled.


I can see why for SEO's sake you would want to have the most informative url possible but I am just trying to see if using the primary key is a security risk or simply just bad form.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

感情废物 2024-07-21 15:12:30

您总是希望向用户提供一个漂亮的 URL,而不是一些令人讨厌的自动生成的 ID。 但我认为你不应该将“友好网址”作为主键。 您仍然应该使用“经典”自动递增的数字 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? 是啊。 使用它们作为主键? 一定不行。

You always want to present the user with a nice URL-not some nasty auto-generated ID. But I dont think you should make said "friendly url" the primary key. You should still use a "classic" auto-incremented, numeric PK and have a second column that is a unique "friendly url". Why?

  1. All the comment tables, ratings
    tables, whatever tables that have a
    relationship with your content table
    can use the numeric primary key.
    This means smaller indexes and lower
    memory use.
  2. Somebody will want to
    change the friendly url. If you've
    got a numeric primary key, you don't
    have to update any of your dependent
    tables (or have the DB do it via a
    cascading update).
  3. In the future,
    you can abstract out the URL bits
    into another table. Said table can
    then store "legacy" URL mappings
    that issue redirects to the primary
    "real" URL map. Then when the user
    wants to change the friendly URL,
    you don't have to break the all the
    inbound legacy URL's. Couldn't do
    this if your primary key was the
    "friendly URL".
  4. I'd still be inclined to use the numeric primary key in all my AJAX goo (for example, a post_new_comment() javascript function would take the primary key, not some friendly URL). The only time I'd use the friendly URL is in any user-facing URL structure.
  5. As for security? If your content is access controlled, you are gonna have to check access no matter if it is the primary key or some friendly URL.
  6. If you allow ways to get to the content via the primary key, people might try plugging in random ID's. If your requirement for not only limited access to content, but the denial said content exists, it is a matter of the phrasing of your errors. It is the same as with login failures--you dont say "username not found" you say "bad username or password". Plugging in random values to find content is gonna be a problem for any approach you take, it is just that with numeric keys there is way fewer values to try.

Bottom line: Friendly URL's? Hell yeah. Using them as the primary key? Hell no.

时光沙漏 2024-07-21 15:12:30

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

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

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

    <前><代码>http://digg.com/space/Liquid_Water_Recently_Seen_on_Mars_2

    这意味着标题至少是主键的一部分,因为这是识别链接旨在针对哪个故事的唯一方法。

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

As you said, the point of putting titles directly in the URL is SEO. Having keywords in the URL has a significant effect on search engine results.

However, a few other thoughts related to your examples:

  • I'm not sure why you assume that the reddit alphanumeric key is not the primary, there's nothing that forces primary keys to be numeric. If it's a unique identifier for the post, there's no reason not to use it as the primary key (or at least part of it).
  • Digg actually enforces uniqueness of titles (perhaps just inside a particular category, I haven't been to Digg in years, so I can't recall). I used to see this fairly often with a duplicate story having a URL like:

    http://digg.com/space/Liquid_Water_Recently_Seen_on_Mars_2
    

    This implies that the title is at least part of the primary key, since that's the only way to identify which story the link was intending to be aimed at.

There isn't really any significant security risk with using the primary key in the URL, other than the ability for people to guess/predict other ones, as pantulis mentioned. But you shouldn't be relying on "nobody will guess this" as a security measure anyway.

眼中杀气 2024-07-21 15:12:30

如果您在URL/链接中包含主键,那么您必须创建某种临时合成键,并且,然后,您必须保存该键的映射在用户的会话中。 这会为您的应用程序添加更多状态/内存使用/需要中断的内容。

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

If you don't include the primary key(s) in the URL/link, then you have to make some kind of temporary synthetic key, AND, then, you have to save the mapping of that key in the session for the user. This adds more state / memory usage / something to break to your application.

If the value is truly sensitive, this might be worth the cost of hiding it. However, obscuring the key doesn't really make it secure, does it? You need to check user roles in whatever "controller" (servlet, code-behind, whatever) before granting access to the item.

小耗子 2024-07-21 15:12:30

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

It isn't inherently a security risk, though it does tell external entities things about your system, which is generally good practice to avoid.

强辩 2024-07-21 15:12:30

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

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

Reddit use numeric ID as well, but converted using Base 36, so it appears as a string. It's like hexadecmial number, which in fact is a string as well. The only difference is the base.

Base 36 is "the most compact case-insensitive alphanumeric numeral system using ASCII characters" and it's easily encodable and decodable. Why 36? A-Z = 26 + 0-9 = 10.

樱花坊 2024-07-21 15:12:30

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

A con: any visitor can easily try and guess other IDs, which may not be what you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文