V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
felix9ia
V2EX  ›  Web Dev

应不应该把主键 id 暴露在 url 上?

  •  1
     
  •   felix9ia · 7 小时 26 分钟前 · 3577 次点击

    想请教一下大家是怎么做的?

    比如访问一个电商网站的店铺页面的 url:

    方式 1:使用自增的主键 id xxx/shop/123

    方式 2:使用雪花主键 id 或者 guid

    xxx/shop/1881238297653633026

    xxx/shop/85d93ea0-3d43-48c5-99ec-e11f54655228

    方式 3: 使用业务编号

    xxx/shop/st_003

    方式 4:

    用 sqids 把所有的实体主键 id(private_id) 在转换 VO 时加盐转换成 (public_id) 返回给前端

    相关讨论: https://www.reddit.com/r/csharp/comments/rg7xob/is_it_bad_to_expose_primary_key_to_the_user_if/

    53 条回复    2025-01-21 18:58:53 +08:00
    Rickkkkkkk
        1
    Rickkkkkkk  
       7 小时 23 分钟前
    不是自增的就行
    javalaw2010
        2
    javalaw2010  
       7 小时 22 分钟前
    在绝大部分场景下,我推崇方案 1 ,如果有产品端/安全端的特殊需求,我会考虑方案 3 ,只有再极少数场景下,比如日志追踪等,我会考虑 2
    javalaw2010
        3
    javalaw2010  
       7 小时 20 分钟前
    @javalaw2010 原贴编辑过了吗?我这里的方案 3 指的是加盐,方案 2 指的是 uuid
    laobobo
        4
    laobobo  
       7 小时 18 分钟前
    我(前端)做过的功能,后端给几乎都是用的自增 ID ,极少数场景才会用 2 ,其他目前没遇到
    felix9ia
        5
    felix9ia  
    OP
       7 小时 18 分钟前
    @javalaw2010 是的,不好意思,我刚刚改了一下。

    其实方案 1 的自增有明显的缺陷,不应该被推荐把? 用 sqids 加盐我觉得也是少数场景,比如用户主页这种。
    CHTuring
        6
    CHTuring  
       7 小时 16 分钟前
    2 就够用了,还是像楼上说的,只要不是自增就行了。
    felix9ia
        7
    felix9ia  
    OP
       7 小时 15 分钟前
    @laobobo 其实,我的这个问题有场景限制,就是在客户端,而不是后台管理页面。

    如果是后台管理,我觉得暴露自增 id 没有关系。
    felix9ia
        8
    felix9ia  
    OP
       7 小时 12 分钟前
    方案 4 有一个好处就是,定期更换盐,可以让链接失效,当然让链接失效有好处也有坏处
    laobobo
        9
    laobobo  
       7 小时 11 分钟前
    @felix9ia 嗯,如果是用户端,个人感觉还是不要暴露自增 id ,总感觉不安全
    javalaw2010
        10
    javalaw2010  
       7 小时 9 分钟前
    自增 id 除了暴露数据量之外,其他我也没觉得会有啥缺陷,而“暴露数据量”这件事也只有少数场景下才值得被关注,这些场景下就需要具体问题具体分析,比如订单相关场景,其实订单号比 ID 更像事实上的主键(我个人喜欢在绝大多数场景下都保留自增 ID ),业务上基本使用订单号而非主键。
    iyiluo
        11
    iyiluo  
       7 小时 8 分钟前
    肯定不能用自增,首先安全那关就过不去,可以被黑产猜测到数据,遇到爬虫,直接把你整个业务的数据都扒下来。用 md5, uuid, 雪花都行
    anonydmer
        12
    anonydmer  
       6 小时 48 分钟前
    目前项目都用 ULID
    musi
        13
    musi  
       6 小时 45 分钟前
    暴露自增 id 有什么问题吗?
    我没见 v2 有什么安全性问题啊
    zpfhbyx
        14
    zpfhbyx  
       6 小时 41 分钟前
    数字没问题啊, 只要不是自增就行 足够大 轮训不全的.
    felix9ia
        15
    felix9ia  
    OP
       6 小时 40 分钟前
    @musi V2EX 用的是自增 id ?

    https://www.v2ex.com/t/1106781
    musi
        16
    musi  
       6 小时 39 分钟前
    @felix9ia t 后面的不就是帖子 id 么,你加一减一不也能看到其他帖子么
    mxT52CRuqR6o5
        17
    mxT52CRuqR6o5  
       6 小时 38 分钟前
    也可以用对称加密算法加个密,不知道密钥的话也破解不了
    felix9ia
        18
    felix9ia  
    OP
       6 小时 38 分钟前
    @musi 卧槽,还真是
    kingcanfish
        19
    kingcanfish  
       6 小时 30 分钟前
    其实 暴露在 url 上和暴露在接口 json 中没啥区别,不自增就行
    飞书一样暴露出来的
    hertzry
        20
    hertzry  
       6 小时 27 分钟前 via iPhone
    京东这一串应该也是自增。
    https://item.jd.com/product/7323507.html
    DonaldY
        21
    DonaldY  
       6 小时 23 分钟前
    @musi
    @felix9ia
    直接用自增 id ,方便爬虫穷举。

    有权限的数据页面不应该用自增 id 在 url 上
    dylanqqt
        22
    dylanqqt  
       6 小时 23 分钟前
    我想问一下自增的有什么风险?
    jaylee4869
        23
    jaylee4869  
       6 小时 12 分钟前
    @dylanqqt 没有做好数据权限控制会导致数据泄露的越权操作。
    BeijingBaby
        24
    BeijingBaby  
       6 小时 9 分钟前
    安全性上讲,无所谓自增,有人说方便爬取,想多了。你随机 id 要爬取你也能爬到啊,只要数据是公开的,和自增和随机的没任何区别。
    有时候更多的是考虑暴漏业务数据量,以及分布式的时候,才抛弃自增 id 。
    zt5b79527
        25
    zt5b79527  
       6 小时 7 分钟前
    @dylanqqt 简单来说,别人能猜到你的数据量。比如说订单号自增,竞争对手就能知道你的订单量。比如之前 b 站的 bv 号,最初好像也是自增的,竞争对手就能知道平台的投稿量,后来就换成随机的了(应该不全是这个原因,但是肯定有这方面的考量)
    esee
        26
    esee  
       6 小时 5 分钟前
    主键用的自增 ID, 后端接口查询的时候,sql 语句对 id 加密查询出来,我是这样做的.
    musi
        27
    musi  
       6 小时 5 分钟前
    @DonaldY #21 简单的数字我也可以穷举吧
    zjsxwc
        28
    zjsxwc  
       6 小时 4 分钟前
    自增 id 方便调试和 dba 维护,大部分时候自增 id 就够用了,
    我只在 serverless 系统上看到用 uuid 的
    wangtian2020
        29
    wangtian2020  
       6 小时 4 分钟前
    可以暴露,暴露在 url 中与暴露在请求体里有什么区别。
    问题是不要使用自增 id 暴露网站后台的规模!
    订单 id 自增暴露每日订单数量,商品 id 自增暴露订单数量
    dylanqqt
        30
    dylanqqt  
       6 小时 0 分钟前
    @zt5b79527 这种算不上什么,自增 id 可以从 1 开始自增,也可以从 10000000 开始自增,别人咋看?至于小公司根本不在乎这个 id 暴露。
    chendy
        31
    chendy  
       6 小时 0 分钟前   ❤️ 1
    暴露 id 本身没啥问题
    暴露 id + 自增 id 可能导致的问题:
    1. 对外的系统,纯自增 id 可以推算出数据增长量,暴露业务情况
    2. 如果权限做的不好,用户或者爬虫可以通过 id 遍历全部数据
    处理方式也很简单:
    1. 用一些操作对数据进行加密/编码
    2. 完善权限,完善风控
    yelog
        32
    yelog  
       5 小时 57 分钟前
    @dylanqqt 容易被暴力攻击越权漏洞, 假如微博的私信列表有越权漏洞

    你在进入微博的私信页面, 发现获取私信列表的接口是 weibo.com/p_message/16645, 然后你把最后的数字(id) 改为 1, 发现获取到管理员 admin 的私信列表了哈哈哈, 然后依次加 1, 可以非常快把微博的所有用户的私信列表全部下载下来

    如果不是自增的, 比如 UUID, 尽管知道这个接口越权漏洞, 但是鉴于 UUID 的随机性和位数, 用户隐私泄漏的风险就非常小
    TimePPT
        33
    TimePPT  
       5 小时 54 分钟前
    @chendy 完全同意,其实主要问题就是推断业务增长情况,和遍历爬虫(一个冷知识:QQ 邮箱的数字 @qq.com 也有类似问题所以一开始入信反垃圾策略就很严格),其他没啥大问题。

    我新项目一般数据库用 PostgreSQL ,唯一 id 使用 uuidv7 ,传给前端 url 外显时候使用 url safe 的 base64 显示了,除了丑点没啥其他副作用。
    cxxlxx
        34
    cxxlxx  
       5 小时 53 分钟前
    liuidetmks
        35
    liuidetmks  
       5 小时 52 分钟前
    @dylanqqt 从 1w 开始,并不能起到很大作用,人家只有作差分就能获取你某段时间内业务规模了
    自增 id 也有其他风险,
    比如某个接口配置失误,通过订单号直接查询数据,还是比较危险的
    importmeta
        36
    importmeta  
       5 小时 51 分钟前
    里面逻辑再拿用户 id,加一层保险
    SoyaDokio
        37
    SoyaDokio  
       5 小时 51 分钟前
    根据 RESTful 语义原则,当然是把 ID 放在 URL 里更好,但仅限于 UUID 或其他类似主键。
    自增主键的话,建议还是隐藏起来,以免用户可以轻松批量暴库。
    default996
        38
    default996  
       5 小时 41 分钟前
    通常建表时我会创建 id,created_at, updated_at
    然后一般情况下我会使用自增 ID;
    特殊情况下,我会使用 id+created_at ,只有两个都匹配到才能查询到记录
    Reficul
        39
    Reficul  
       5 小时 15 分钟前
    自增 ID 可能会暴露你们业务一天有多少数据,比如订单量之类的。之前我们懒惰 fix 这个问题的方法是随机跳过部分数字来给数据投毒。
    voy
        40
    voy  
       4 小时 55 分钟前
    hackernews is self increased. done.
    forty
        41
    forty  
       4 小时 54 分钟前   ❤️ 1
    有时候杀鸡用不上牛刀。

    其实还有 1 种简单方案,叫 hashid, 几十种语言的实现都有, github 可用搜到,可以在纯数字和"hashid"之间互相转换,既不直接暴露主键数字 id 给前端,无法被人直接遍历,同时也不增加后端复杂度。
    Hashids 改名叫 Sqids 了. https://sqids.org/

    原来 @cxxlxx 已经提出来了,刚开始没注意到。
    thinkershare
        42
    thinkershare  
       4 小时 51 分钟前
    自增的也无所谓,需要安全的地方,需要其它权限鉴定逻辑。
    ntedshen
        43
    ntedshen  
       4 小时 48 分钟前
    如果你用 innodb 的话,可以把 update 全部改成 insert ignore on duplate update ,你就能得到一个超音速自增的主键(狗头
    Zcyisabigman
        44
    Zcyisabigman  
       4 小时 48 分钟前
    用自增的一些缺点:
    1 ,暴露业务数据规模,著名的瑞幸咖啡那件事就是被人蹲点捡小票,通过 ID 推算真实业务量
    2 ,方便爬虫写脚本抓数据
    3 ,存在缓存击穿问题???
    chairuosen
        45
    chairuosen  
       4 小时 47 分钟前
    要看业务是不是数据都公开,京东的商品,论坛的帖子,这种无所谓。资源要做隔离的就需要考虑隐藏了
    xuelu520
        46
    xuelu520  
       4 小时 40 分钟前
    暴露有什么影响吗?
    有些 ID 暴露也无所谓啊,就例如这个帖子的 ID 不就在 url 上
    涉及到隐私和安全的可以考虑加密或雪花或其他方案加密。
    正常用的无所谓的,做好暴露后问题的处理就行。
    nekochyan
        47
    nekochyan  
       4 小时 20 分钟前
    我们有个项目是直接用 ID 异或一个较大的数给前端就行了,然后再异或回来
    zt5b79527
        48
    zt5b79527  
       4 小时 1 分钟前
    @dylanqqt #30 单单业务规模这一点,确实对小公司可能不算什么,那大公司呢?如果是年营收上百亿,竞争对手虎视眈眈的上市公司呢?对于大公司来说,安全才是第一位的。竞争对手可能已经通过各种渠道收集了你各种各样的信息,再加上这一点交叉验证,底裤都给你扒出来。
    ospider
        49
    ospider  
       3 小时 58 分钟前
    snowflake id 就足够了,别的纯属想太多
    yh7gdiaYW
        50
    yh7gdiaYW  
       3 小时 46 分钟前
    看完这贴我就把 v 站的第 1,10,100,1000,10000,100000,1000000 贴看了一遍
    对很多业务来说这么轻易的能跳转是不可接受的
    lcy630409
        51
    lcy630409  
       3 小时 19 分钟前
    自增 id 然后商户可以 缴纳 30 元 自定义一个“靓号”
    xuanbg
        52
    xuanbg  
       3 小时 15 分钟前
    不连续就行了
    spike0100
        53
    spike0100  
       2 小时 53 分钟前 via iPhone
    可以考虑 hashids 对主键进行映射
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2919 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 13:52 · PVG 21:52 · LAX 05:52 · JFK 08:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.