长期的用户令牌是如何存储的呢?存储结构是什么样的?
背景
一般来说 session 存储可以只生成一个随机 sessionId ,存在缓存中,value 是用户信息,返回给客户端可能是一个 cookie 里面的 token 之类的或者就叫 sessionId ,需要鉴权时候先拿 sessionId 找用户信息,再拿用户信息判断权限。
这种对于长期的令牌看起来就没有那么友好,如果申请一个令牌存在数据库内,然后直接对着这个令牌赋权,那数据库泄露就寄了,一般密码还会 md5 或者 hash 一下存,但 token 完全是个随机值,hash 一下就找不到了,那么 token 直接明文存看起来比密码还不安全,虽然 token 泄漏和密码泄漏危险性也不一致,但总觉的不太合适。
这就引出一个问题,是否要在 token 里面带上用户信息?
方法 1:token 里面带用户信息
比如我 token 由用户名+token 名+secret 组成,存储时候存 用户名,token 名,md5(secret),查询时候先把 token 解析出用户名和 token 名,然后跟查密码一样确认 token 是否合法。
想讨论的问题
这个方法看起来没什么问题,相当于带上用户名和密码来访问了,不过这方法就需要各端协商出一个统一的解析方式。
这其实很容易想到 JWT ,可能这里直接用 JWT 就好了,还能帮忙做防篡改等措施,不过 JWT 设计的正常用法是无状态的,他会带来一个吊销困难的问题,感觉也很少长期 token 的设计会使用 JWT 的,而如果我把 JWT 有状态的使用看起来就有点怪。现实情况是否有人拿 JWT 做有状态 token 的呢?或者是否有其他比较好的方法吗?
方法 2:用户传 token + 用户信息
还有种方式是,把 token 就当作密码,每次登录时候用 token 代替密码登录,比如 git push 时候用的 token 就很像。
想讨论的问题
不过他实际存储时候是否是明文存储呢?如果是用的 hash 值存储,那如果一个用户有多个 token ,那是不是就得校验多次呢?并且 token 还能细分权限比如 api 的读写区分,还有项目 token ,ci token 等等,token 多起来之后索引是如何解决的呢
