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

单机服务端使用 token 策略是怎样的?

  •  
  •   tctc4869 · 2020-05-25 14:56:06 +08:00 · 3264 次点击
    这是一个创建于 1644 天前的主题,其中的信息可能已经有所发展或是发生改变。

    之前为页面端,也就是浏览器端,用户操作,是提供基于 session 登录,现在要弄非浏览器端,也就是 app 端,那么依赖 cookie 的 session 就不行了。

    得用 token 。单机服务端使用 token,一般是用带有超时设定的缓存框架来存储在线用户状态的么?比如 guava 或 Caffeine

    另外最简单的 token 码是怎样的?把 user_id 和和登录时间 hash 个字符串,再把哈希的登录信息作为 token,传给 app 端有什么问题么?

    token 要加密?听很多人说必须要对称加密,至少 des,aes 。那 base64 行不行,对称加密真的是必须的么?只用 hash 过的做 token,还有什么安全问题么?

    第 1 条附言  ·  2020-05-26 10:17:08 +08:00
    如果增加 app 端的话,怎样尽可能减少后端的改动?在保证 app 端有登录之后,在过期之前的自动登录功能?
    第 2 条附言  ·  2020-05-28 09:26:58 +08:00
    我用的 jwt 是 jose4j,我直接用对称加密的方式,通过 JsonWebEncryption 创建一个 jwt 对象,然后 setpayload 加密数据,把加密的 token 直接传给客户端合适么?
    18 条回复    2020-05-27 18:35:57 +08:00
    sayitagain
        1
    sayitagain  
       2020-05-25 15:03:32 +08:00
    user_id+登录时间。。。那光脚也能随便猜个 token 出来啊。。。实在不济加个随机 salty 也能撑啊
    tctc4869
        2
    tctc4869  
    OP
       2020-05-25 15:06:49 +08:00
    @sayitagain 我目前觉得,能 hash 的话,就不想搞什么对称加密,但我也不一定会用“user_id+登录时间”,可能会用 app 端的唯一信息,比如设备码之类的(就算只用登录 id+时间,我生成的比较复杂点的 hash 组合)
    whitehack
        3
    whitehack  
       2020-05-25 15:11:38 +08:00
    > token 要加密?

    这是把数据加密一下,加密成 token, 发给客户端,服务端收到 token 再解密.得到用户数据,过期时间等.
    所有需要对称加密.


    > user_id 和和登录时间 hash 个字符串

    这种需要把 hash 对应的用户数据存储在服务端内存或者 redis 之类的地方. 然后服务端收到这个 hash 去内存或者 redis 取数据.



    两种都可以. hash 对 token 的可控性强吧. 对称加密那种就是不需要依赖存储,在分布式的服务上比较方便. jwt 应该就是这种的.
    Zach369
        4
    Zach369  
       2020-05-25 15:12:28 +08:00
    我目前生成 token 一般都是使用 jwt
    tctc4869
        5
    tctc4869  
    OP
       2020-05-25 17:23:45 +08:00
    @whitehack 问一下,app 端登录后,想减轻权限验证的服务端性能负担,将 RBAC 权限的关于单个用户的验证数据加密到 token 中,这个策略有问题么。
    tctc4869
        6
    tctc4869  
    OP
       2020-05-25 17:24:25 +08:00
    @tctc4869 把角色 id 加密的用户 token 里
    mgcnrx11
        7
    mgcnrx11  
       2020-05-25 17:33:34 +08:00
    app 端把 sessionid 当作 token 处理不香吗?后端连改也不用改。
    dilu
        8
    dilu  
       2020-05-25 17:36:45 +08:00
    你不要想那么多那么复杂

    建个数据库,uid 和 token 映射,你的 token 怎么生成都行

    然后请求过来了 根据 token 查 uid 就行

    这是最简单的
    tctc4869
        9
    tctc4869  
    OP
       2020-05-25 17:56:52 +08:00
    @mgcnrx11 可以这样?你确定不用改?

    app 端发起登录请求的时候,如果登录成功,则获取 request 里的那个 session 的 sessionid ?
    mgcnrx11
        10
    mgcnrx11  
       2020-05-25 18:02:51 +08:00 via iPhone
    @tctc4869 登陆成功,响应 header 里面会有 set-cookie,sessionid 就在里面啊。提取出来后,后续请求发起的时候 app 端再把 sessionid 放回去 cookie 头的位置
    wangxiaoaer
        11
    wangxiaoaer  
       2020-05-25 18:26:50 +08:00 via Android
    Jwt 失效问题怎么解决呢?
    malusama
        12
    malusama  
       2020-05-25 18:32:35 +08:00
    JWT 不香嘛?
    guiling
        13
    guiling  
       2020-05-25 18:37:52 +08:00 via Android
    直接 jwt 吧,token 里可以放一些用户标识,不要放密码之类的数据
    xcstream
        14
    xcstream  
       2020-05-25 18:41:36 +08:00
    随机生成个 token
    token 对应 userid 保存到 redis 里
    tctc4869
        15
    tctc4869  
    OP
       2020-05-26 10:15:59 +08:00
    @mgcnrx11 有几个问题,

    怎么配置 app 端比浏览器端,登录之后的过期时间比浏览器端长一点,是在客户端本地存储的 token 里存带有过期时间数据?然后编写个 action 来解决 app 端非过期自动登录问题?

    还有,一些请求原本是返回页面的,也设置了 reuqest.setAttribute 和模板引擎来将一些数据渲染到页面,而增加了 app 端之后,这些请求中渲染到浏览器端的响应数据,现在如果 app 端请求,就得要传值到 app 端,岂不是还得在开几个单独的 action ?或者编写 if 判断代码判断是不是带有 token 的 app 端?

    在 postman 上测试了,app 端如果访问不是 @ResponseBody 的请求,就会遇到跨域问题。
    mgcnrx11
        16
    mgcnrx11  
       2020-05-26 13:45:46 +08:00
    @tctc4869

    1. 如果是用 sessionid 代替“Token”的话,这个估计没有办法,毕竟过期还是后端来控制的,一般环境过期时间都是一个全局配置。而且,Session 的过期时间是“从 session 不活动的时候开始计算,如果 session 一直活动,session 就总不会过期”。

    2. 请求数据的 request 里面,accept 头就是‘Accept: application/json“,页面的话是不同的( Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 )

    3. 跨域在 app 用的库可以忽略吧?或者 cors
    tctc4869
        17
    tctc4869  
    OP
       2020-05-27 17:05:16 +08:00
    @guiling
    @malusama

    jwt,这个方式跟把生成的 token 信息进行直接加密(对称,非对称)有和区别?
    guiling
        18
    guiling  
       2020-05-27 18:35:57 +08:00 via Android
    @tctc4869 自己实现也可以,非对称用 md5 当 token,但需要自己记录维护,用 jwt 不需要额外维护,token 信息分三段,你存在 token 里的数据只是 base64,所以不要存私密信息,有一段是用来检验数据是否被篡改的,加密算法配置里可以换,缺陷就是不能续期,不能销毁
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1467 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:57 · PVG 00:57 · LAX 08:57 · JFK 11:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.