V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Game Engines
Unreal Engine
MyCryENGINE
dzmcs
V2EX  ›  游戏开发

网页游戏, websocket 通信,一般怎么处理用户认证?

  •  
  •   dzmcs · 2020-12-16 17:37:46 +08:00 · 5863 次点击
    这是一个创建于 1423 天前的主题,其中的信息可能已经有所发展或是发生改变。

    使用 websocket 和 protobuf 做通信,用户身份标识一般用 session 还是 jwt ?或者别的什么方式呢

    23 条回复    2020-12-17 14:18:38 +08:00
    netnr
        1
    netnr  
       2020-12-16 18:51:00 +08:00 via Android
    我觉得优先考虑无状态的方式,自由好扩展
    KuroNekoFan
        2
    KuroNekoFan  
       2020-12-16 19:15:01 +08:00
    可以结合起来用啊
    RedBeanIce
        3
    RedBeanIce  
       2020-12-16 19:38:09 +08:00
    不知道楼主有没有写过 websocket 通信,,如果是前端 H5 websocket,后端 netty,在后端接收的时候,其实也是有一个 channel 的接收的,可以在那里认证。
    sunny352787
        4
    sunny352787  
       2020-12-16 19:55:17 +08:00
    都不用,按 tcp 方式验证,建立连接之后先发个认证消息到服务器
    Mutoo
        5
    Mutoo  
       2020-12-16 21:12:59 +08:00   ❤️ 1
    websocket 建立连接后的第一个 protobuf 协议,由 client 发送认证信息(可以是 jwt,可靠性比较高,无状态易扩展 ) ,服务端验证有效后保持通讯。无效的话直接断开通讯。后续的通信就不需要再验证了。
    Mutoo
        6
    Mutoo  
       2020-12-16 21:14:05 +08:00
    接上,获取 jwt 的方式可以用一般的 oauth 协议。负责登陆的服务器可以跟游戏后端分离( jwt 的另一个好处)
    aaronlam
        7
    aaronlam  
       2020-12-16 21:37:26 +08:00
    @Mutoo 请教一下,那像 jwt 的失效处理,你们一般是怎么处理的呢?是后端有有个 Redis 专门存用户的 jwt 吗?
    aaronlam
        8
    aaronlam  
       2020-12-16 21:41:18 +08:00
    @aaronlam 补充一下,准确的说就是,比如:用户修改了密码,我想让他先前所登录生成的 jwt 失效,让其重新登录的这种情况。
    lqw3030
        9
    lqw3030  
       2020-12-16 21:45:13 +08:00 via iPhone
    在 websocket 协议升级前的 http 上做
    Leigg
        10
    Leigg  
       2020-12-16 21:58:43 +08:00 via iPhone
    当然不能用 jwt 了,因为你很可能需要实时控制用户的会话生命周期,比如踢下线。
    Yoock
        11
    Yoock  
       2020-12-16 22:13:09 +08:00
    1. 傻一点的办法: 每个包都带验证信息
    2. 在每一个 connect 里保存验证信息,有用户登录广播,然后踢掉旧的 connect
    abersheeran
        12
    abersheeran  
       2020-12-16 22:32:48 +08:00
    浏览器的 websocket 接口,不能自定义 header,只能通过带 cookie 的方式认证。或者你把认证做进 websocket 交互里,不过更推荐用 cookie 。
    Austaras
        13
    Austaras  
       2020-12-16 23:47:26 +08:00
    讲个邪道:其实 websocket 可以自定义 header,只不过只能自定义 protocol,就用那个当作鉴权
    2kCS5c0b0ITXE5k2
        14
    2kCS5c0b0ITXE5k2  
       2020-12-16 23:54:23 +08:00
    @Mutoo 用 jwt 就无法踢下线了。
    v25217
        15
    v25217  
       2020-12-17 00:24:15 +08:00 via Android
    @emeab 可以踢呀,服务器直接断开 websocket 链接就行
    Mutoo
        16
    Mutoo  
       2020-12-17 06:31:02 +08:00   ❤️ 2
    @aaronlam 失效处理有很多种方式,因为登陆验证只需要在第一个协议处理,可以设置很短的 expired 让 jwt 失效,没有保存的意义。之后 websocket 连接本身是有状态的。

    踢下线直接断开 websoket 即可,下次登录需要重新验证。

    至于修改密码的问题,按标准的 OAuth 的流程来处理就好了。
    Mutoo
        17
    Mutoo  
       2020-12-17 07:05:00 +08:00   ❤️ 2
    接上,登陆验证用的其实就是一个生命周期很短的 access token 。而存在本地的是 refresh token,用于获取新的 access token,有效期相对长一些。

    refresh token 可以记录用户上次改密码的时间,用户修改密码的话,下次获取 access token 的时候比较最新修改修改密码时间,如果失效就直接拒绝,让重新登陆获取新的 refresh token 即可。
    qwerthhusn
        18
    qwerthhusn  
       2020-12-17 08:52:12 +08:00
    Upgrade 前做
    dzmcs
        19
    dzmcs  
    OP
       2020-12-17 09:59:21 +08:00
    @qwerthhusn 感谢,明白了
    joesonw
        20
    joesonw  
       2020-12-17 10:17:31 +08:00
    Upgrade 的时候可以拿到请求头, query 等这些, 和 http 一样处理呗.
    aaronlam
        21
    aaronlam  
       2020-12-17 11:58:29 +08:00
    @Mutoo

    喔,有点恍然大悟的感觉,感谢!
    以往我以为都是只生成一个 token 。如果是按照你的说法有 access 和 refresh 两个 token,再进行配置短命的 access token,配置 refresh token 里的最新修改密码时间的确可以办到踢下线,不过感觉这样好像没办法做到立即踢下线的效果。。
    Mutoo
        22
    Mutoo  
       2020-12-17 12:26:17 +08:00   ❤️ 1
    @aaronlam 玩家修改密码的时候,给后端一个消息。后端收到消息查看是一玩家是否有连接,有的话发个下线协议,然后主动断开 socket 即可。完全后端可控,不需要前端参与。前端下线后原有的 refresh token 根据上述业务逻辑就自动失效了,需要重新登录。
    aaronlam
        23
    aaronlam  
       2020-12-17 14:18:38 +08:00
    @Mutoo 再次感谢!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2811 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 14:02 · PVG 22:02 · LAX 06:02 · JFK 09:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.