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

请教大家 WebSocket 鉴权问题

  •  1
     
  •   sdbybyd · 2020-10-04 13:39:01 +08:00 · 8356 次点击
    这是一个创建于 1504 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前项目用 jwt 做 http 的鉴权,保存在 cookie 中,但是 websocket 不能使用 httponly 的 cookie, 看了淘宝还有 fb 的方案,都是用 url 参数带个 token 或者 sessionId 过去后端, 请教下前端如何获取这个发送的 token,或者 ssid,直接请求后台:GET /token 获取吗?这样是否安全

    23 条回复    2020-10-06 21:36:35 +08:00
    ila
        1
    ila  
       2020-10-04 13:48:58 +08:00 via Android
    wss,每次请求加上 token
    wd
        2
    wd  
       2020-10-04 14:08:41 +08:00 via iPhone
    websocket 按说也是个 http 你可以在 upgrade 连接前判断好 不合规就给它断开
    wd
        3
    wd  
       2020-10-04 14:09:22 +08:00 via iPhone
    哦 http olny 好吧..
    leyle
        4
    leyle  
       2020-10-04 14:19:48 +08:00
    ws 是个长连接。可以先允许任何 client 与 server 建立连接,然后 server 判断当前用户是否鉴权。
    正常请求下,ws client 发起对 server 的连接后,就能够主动 /被动的发送 token 给 server 。
    server 可以对未发送 token 的 client 发送要求发送 token 的“指令”,如果在一个 X 秒内没有收到 client 发送过来的 token,server 就可以主动断开连接。如果同一个 client 多次发起连接且没有鉴权成功,就用其他机制限制链接一段时间。
    sdbybyd
        5
    sdbybyd  
    OP
       2020-10-04 14:51:12 +08:00
    @leyle 这个 token 怎么来呢,重 cookie 提取吗? httoonly 的 cookie 没办法
    sdbybyd
        6
    sdbybyd  
    OP
       2020-10-04 14:51:44 +08:00
    @wd 这个思路有想过 不过感觉还是有点奇怪
    JimmyChange
        7
    JimmyChange  
       2020-10-04 15:08:02 +08:00 via iPhone
    在建立 websocket 链接的请求可以读取 cookie 吧?就是需要返回 101 的那个请求里

    要是使用 token,直接提供给 api 获取 token 就好了吧
    Arrowing
        8
    Arrowing  
       2020-10-04 15:11:01 +08:00
    有个思路不知道行不行
    就是客户端请求服务器的时候,将客户端特征信息(记为 ID )保存下来,保证唯一性(这个得自己想法子)。
    在 Redis 里,保存对应的状态。
    每次内容到服务器就到 Redis 里去找这个 ID,查找对应的状态。
    momocraft
        9
    momocraft  
       2020-10-04 15:27:57 +08:00
    用 cookie 換一個一次性 token,用那個 token 連接?
    sdbybyd
        10
    sdbybyd  
    OP
       2020-10-04 16:54:23 +08:00
    @JimmyChange 这样可能有安全问题,httponly 属性就是为了前端无法读取 cookie 里面的 token,暴露这个 API 感觉不太好
    sdbybyd
        11
    sdbybyd  
    OP
       2020-10-04 16:55:03 +08:00
    @Arrowing 你这个思路就是 jwt 了,关键前端如何通过 websocket 吧这个东东发给后台
    sdbybyd
        12
    sdbybyd  
    OP
       2020-10-04 16:58:25 +08:00
    感觉还是在 beforeHandshake 这个 hook 上动手脚
    micean
        13
    micean  
       2020-10-04 19:29:52 +08:00 via Android
    ws 连接的时候也有 cookie 啊,跟 httponly 没关系吧
    既然是 httponly,说明是服务端自己管理令牌,但是换成 ws 却管理不了了?
    我不太明白……
    yc8332
        14
    yc8332  
       2020-10-04 20:18:29 +08:00
    和 http 一样啊。。websocket 本来就是基于 http 的
    yogogo
        15
    yogogo  
       2020-10-04 20:45:57 +08:00 via Android
    token 是前端请求登入的时候后端返回的,然后前端每个请求都要带上 token,websocket 一样道理
    xrr2016
        16
    xrr2016  
       2020-10-04 20:53:55 +08:00
    第一次建立 ws 链接的时候用的是普通的 http 协议,之后才是 ws
    hijoker
        17
    hijoker  
       2020-10-04 20:59:59 +08:00
    登陆,鉴权 http 服务, 返回 token,连接 ws,需要带上这个 token,后端校验 token,成功就连接,不然就断开
    pagepancn
        18
    pagepancn  
       2020-10-05 00:16:30 +08:00
    @yc8332 不对吧,websocket 是基于 socket 的吧
    abersheeran
        19
    abersheeran  
       2020-10-05 01:43:44 +08:00
    看你的客户端了。如果你客户端包含标准浏览器,那么只能走 url 参数的路子。别问,问就是浏览器标准傻逼,这个玩意他们讨论好几年也没个定论,等确定好了再等实现出来,你估计都 35 岁退休了。

    如果你客户端只是需要满足非浏览器,那简单了,websocket 握手用的 http 协议,你该咋鉴权咋鉴权。
    JimmyChange
        20
    JimmyChange  
       2020-10-05 04:10:04 +08:00 via iPhone
    @sdbybyd 有什么安全问题?又不是让你返回 JWT 的 token,返回个一次性验证 token 不就行了
    jinliming2
        21
    jinliming2  
       2020-10-05 10:29:03 +08:00
    跟 HttpOnly 有什么关系? HttpOnly 的 cookie 在 Websocket 连接的时候也是会正常发送的啊!
    刚刚在 Chrome 和 Firefox 下测试没有问题,标记为 HttpOnly 的 Cookie 在 Websocket 握手的时候都可以正常发送。

    网上搜了一下,只有 2010 年 1 月苹果的 Webkit 存在 bug 导致 HttpOnly Cookie 在 WebSocket 下不发送,但是也早已修复: https://bugs.webkit.org/show_bug.cgi?id=34289

    另外搜到一个 UC 浏览器同样的问题: https://stackoverflow.com/questions/43224033/uc-browser-not-sending-httponly-cookie-for-websocket-calls 估计也是用了那个有问题的版本的 Webkit 内核代码。
    如果确实要考虑这些使用旧版带 bug 的浏览器的用户,这个问题下也给出了参考方案:在 WebSocket 连接建立之后,若用户没有携带 Cookie,则在 Websocket 中给用户一个唯一 ID,用户拿到 ID 之后通过正常的 HTTP 带上 Cookie 请求一个 API,这样就可以将这个 Websocket 连接的 ID 与用户的 Cookie 进行绑定。加个超时自动断开连接就行。
    yc8332
        22
    yc8332  
       2020-10-05 22:00:26 +08:00
    @pagepancn 握手走的 http,只是最后协议升级而已。
    codehz
        23
    codehz  
       2020-10-06 21:36:35 +08:00
    websocket 建议不要玩 http 层的花样,有些浏览器没做好就不会发
    我这里提供一个思路,把 token 编码到 url 路径里,短期且一次性的那种(
    然后用普通 http api 去请求那个 url
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   985 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 22:54 · PVG 06:54 · LAX 14:54 · JFK 17:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.