之前一直在写 iOS ,前后端分离,每次请求带上 token 就行了。
现在想写一下后端,想问一下一般是怎么处理 token 的?
用户登录的时候根据 userID 加上时间戳 或者 加上一个自定义值 用加密算法生成 token 之后,
1.存到数据库中(能设置过期时间吗?),每次客户端请求的时候取出来验证
2.存到 redis 中,设置过期时间,每次客户端请求的时候取出来验证
3.不存,每次客户端请求的时候根据之前的生成方法再生成一次来验证
哪种方法成本更低? 或者有更好的方法吗?
之前一直在写 iOS ,前后端分离,每次请求带上 token 就行了。
现在想写一下后端,想问一下一般是怎么处理 token 的?
用户登录的时候根据 userID 加上时间戳 或者 加上一个自定义值 用加密算法生成 token 之后,
1.存到数据库中(能设置过期时间吗?),每次客户端请求的时候取出来验证
2.存到 redis 中,设置过期时间,每次客户端请求的时候取出来验证
3.不存,每次客户端请求的时候根据之前的生成方法再生成一次来验证
哪种方法成本更低? 或者有更好的方法吗?
1
sfwn Apr 1, 2017
第三种能解释下吗
|
3
lightzh OP @sfwn
例如客户端登录后服务器生成 token 之后返回,之后客户端请求的时候带上这个 token ,服务端每次都根据之前生成的方法(例如加上了自定义值,使用了什么加密算法)再生成一次来比较,一样就验证成功 就是楼上说的 JWT ,我也是刚接触 |
4
horsley Apr 1, 2017
我实现过的是不存,仅验证
|
5
lurenw Apr 1, 2017
有的数据库是支持设置过期时间的, 1 和 2 一个意思。
|
6
ytmsdy Apr 1, 2017
一般都是 token+用户名,在数据库中查询 token 对应的用户名。
如果用户名和客户端发送的一致则继续正常的访问。 如果不一致丢 401 错误。 |
7
jedrek Apr 1, 2017 都不需要存,对用户 ID 和过期时间戳签名即可得到 token 。
token 不应存私密的信息,所以不需要加密。而是要签名,防篡改。 |
8
klesh Apr 1, 2017 via Android 看 jwt 规范你就明白了。
一般不需要存,但若要实现 revoke 之类就要存储 |
9
jedrek Apr 1, 2017 @klesh 比如修改密码后,需要吊销之前的 token ,所以用户 ID 和过期时间戳之外,再加一个值,这个值可存在缓存中,每次请求先对 token 验证,通过后再拿缓存中的值与 token 中的比较
|
10
byfar Apr 1, 2017
登录成功后生成一个 token 存表存 redis 都行
一个 token 对应一个 uid |
11
avichen Apr 1, 2017
JWT : Json web Token ,可以去了解一下
|
12
klesh Apr 1, 2017 @jedrek
这样的流程需要进行, 1 。解码 token , 2 。验证 token , 3 。把值与缓存比对。 我认为不需要所谓的“值”,直接把 token 放到缓存中,利用 set 进行比对是很快的,都不需要解码和验证 token 。同时, token 一定要设定有效期,如一周,这样缓存中只需存最近一周内被 revoke 的 token ,在空间和时间上更合理。如果用户不喜欢每七天登录一次,可以在客户端设计一套自动 refresh token 的机制。 |
13
Ouyangan Apr 1, 2017
直接用 session 吧 ,自己搞来搞去最后都搞成了 session
|
14
sampeng Apr 1, 2017
一直很不理解 token 的使用场景。。。搞来搞去不就是个 session 么?
完整实现了 http 协议的哪个不能支持 session ?还是因为懒 |
15
SourceMan Apr 1, 2017
2
|
17
jedrek Apr 1, 2017 不用 JWT , token 是这样的结构:签名后的字符串-用户 ID-指纹,共三段,每段中划线分隔.由于要谈到 token 吊销需要存储的问题,所以这里可以不需要存时间戳了。
当注册 /登录成功后: 1. 指定一个指纹,任意值都可以,只要这个值对这个用户没有使用过即可。 2. 将指纹和用户 ID 拼起来并签名,组成 签名后的字符串-用户 ID-指纹 这样结构的 token 。 3. 将用户 ID 与指纹对应起来放到缓存中,并且设置缓存过期时间,这个时间就是 token 有效期。 4. 将 token 返回给客户端。 当用户再次请求时: 1. 将 token 中的用户 ID 和指纹再签名(通过服务端私钥),比对提交的 token 签名后的字符串 就可将篡改或伪造的 token 过滤掉了(或许这一步有更好的实现方式)。 2. 过了上一步,仍然无法确定 token 是否已被吊销。获取缓存中的指纹与提交的 token 的指纹比对,若缓存中取不到指纹值(缓存已设置过有效期期)或缓存中的指纹与 token 的指纹值不相符,就说明这个 token 被吊销了。 3. 通过了上面两步,表示这个请求是已认证了的。 |
19
jarlyyn Apr 1, 2017
我是做了一个 cachegroup.
前端 redis 热数据,后端 mysql 全部数据。 另外, token 不是应该随机生成的吗? |
20
ppmoon Apr 1, 2017 推荐楼上说的 JWT ,这种方式比较简单,如果应用安全级别不高很实用。客户端存一份 token ,存哪里都行,然后每次需要权限操作的时候就带着 token 去请求。后端接到请求的时候就验证一下。 JWT 把状态放在客户端,后台压力小,要是使用 session 还需要占用服务器资源。 session 多了还需要去管理 session
|
21
jarlyyn Apr 1, 2017
|
22
kulove Apr 1, 2017
aes 加密用户 id ,过期时间 每次请求解密判断是否过期
|
23
phx13ye Apr 1, 2017
如果 jwt 也要存,不就变成 session 了么,后续又会遇到一对分布式 session 要处理的问题,这样好处在哪?求详细说明
|
25
phx13ye Apr 1, 2017
@avichen 想把 JWT 作为 app 端和网页端登录凭证。那么 logout 的时候,一般也只是客户端删掉 JWT 吗?
假如在 payload 里设置过期时间 60 秒,如何防止在 59 秒还可以成功请求, 61 秒就要求用户重新登录的情况呢? JWT 有自带的机制去处理吗 |
26
vjnjc Apr 1, 2017
1 , 2 看起来一样。 1 的话存的时候带过期时间呀。
3 的话看起来不安全,通过逻辑生成总是有漏洞(/规律) |
27
avichen Apr 1, 2017 @phx13ye #25 logout 时可以采用你说的删除 token ,另外 59 秒的问题,貌似没有解决办法,这一秒请求完了,下一秒再请求,它不就过期了嘛,对你的业务影响会很大吗?
|
28
behappy Apr 1, 2017
@jarlyyn
请教一个问题,假如我先打开网页 A ,这时候服务器在努力运算生成 token,但是出于某种原因卡住了。然后我又开了个新标签仍然打开网页 A, 然而这次服务端生成 token 后很快就返回了然后写入 cookie 成功了。然后前一次的 token 慢悠悠的返回了,把第二次的 token 覆盖掉了。这种情况该咋整 |
31
CareiOS Apr 1, 2017
@sfwn 就是服务器用对称加密,将数据加密得到一个 string ,然后返回给 client, 每次 client 请求都带上这个 string, 服务器收到后解密,判断是否过期等....
|
32
asen477 Apr 1, 2017
一般 app 端存 token 不会做短期的时间验证
一般存在本地都会很长时间。 |
38
sutra Apr 2, 2017
spring-session
|