目前笔者做了一款iOS的App,需要访问服务器资源,当App登录以后,服务器端验证通过后,会返回一个访问token,用于校验后序的api访问操作,App以后所有的请求都会带上这个token参数,现在想问下,这个token如何实现?
有朋友建议我使用session的session id来实现这个token,但是session销毁后,用户就必须重新登录了,你们有什么好的办法么?
1
q84629462 2015-07-02 15:52:58 +08:00 via Android 1
不销毁session不就可以了吗
|
2
xx314327475 OP @q84629462 不销毁session服务器内存可能吃不消,而且我这个服务器在没有访问的时候会自动休眠,session也会被销毁.
|
3
xx314327475 OP @q84629462 可以不用token么?
|
4
xx314327475 OP @q84629462 可以不用session么?
|
5
ipconfiger 2015-07-02 15:59:09 +08:00
直接用oAuth2的方案不行么?
|
6
hahasong 2015-07-02 16:00:28 +08:00
已经登录了为何还要带token识别状态,在服务端根据用户身份处理就好了
|
7
q84629462 2015-07-02 16:01:35 +08:00 via Android
@xx314327475 那就放数据库呗,不就保存一个字符串而已
|
8
BuilderQiu 2015-07-02 16:01:41 +08:00
用户主要信息ID之类的+过期时间+balabala+...
加密生成token,客户端保存 请求时过滤器解密验证 |
9
xx314327475 OP @ipconfiger oAuth2是不是有些过于复杂了?
|
10
xx314327475 OP @hahasong 因为http是无状态的,token是用来校验用户权限的,告诉服务器这用户已经登录了,不用再校验了,具体用他的原因主要是防止其他人盗用api,而且每次app请求都不能带上用户名和密码吧?
|
11
xx314327475 OP @q84629462 每次请求都去数据库查一次么?放内存中如何管理呢?什么时候销毁呢?
|
12
xx314327475 OP @BuilderQiu 客户端保存我是清楚的,token如何生成我也是明白的,我不明白是服务器是如何保存用户的登录状态.
|
13
glasslion 2015-07-02 16:11:22 +08:00
@xx314327475 一个session才多少大小,就能把你们服务器内存给吃光了?
|
14
xx314327475 OP @glasslion 不是怕吃光,但是这种实现感觉总是不好的
|
15
billlee 2015-07-02 16:12:44 +08:00
我自己做的小项目,试过用 redis 保存 session, 感觉还不错。可以设置过期时间,到期 redis 会自动销毁。
|
16
q84629462 2015-07-02 16:13:06 +08:00 via Android
token嘛,多数一个月,有的一年,要看你的账号使用条件,例如异地ip立即销毁,一段时间内多个IP使用立即销毁之类的
|
17
xx314327475 OP @billlee 可是你怎么知道什么时候销毁session呢?session销毁了,我app的用户怎么办?
|
18
xx314327475 OP @q84629462 你的意思是这个不用服务器的session id来做,自己在服务器实现下,然后根据你所说的算法,来用程序销毁
|
19
q84629462 2015-07-02 16:17:54 +08:00 via Android
@xx314327475 token不就为了让用户一次登录长时间免登录么,当然要有安全机制,网络传输被抓包别人就可以用了,毕竟是明文的玩意
|
20
hahasong 2015-07-02 16:18:28 +08:00
@xx314327475 登录态跟web一样,登录完了写sesseion 和 cookie 不就完了,每次请求带上cookie
|
21
nisnaker 2015-07-02 16:20:05 +08:00 1
登录之后在服务端用当前用户的唯一id和时间戳做加密,加密的结果作为token返回给客户端。
之后每次请求带上这个token,服务端解密,如果能成功解密而且时间没有过期,就认为登录成功。 至于其他业务建议跟这个token解耦,该查询的查询,该缓存的缓存,不要把这个token当做session来用(存一些临时的东西神马的)。 |
22
6IbA2bj5ip3tK49j 2015-07-02 16:20:19 +08:00 1
放内存,放token和激活时间,每次访问API都刷新一下token的激活时间。超时的时候删掉就好了。
|
23
q84629462 2015-07-02 16:21:20 +08:00 via Android
token放哪看你服务器条件,内存大的放内存,内存不够大的就只能硬盘存储,不就只有这两种存档方式嘛
你也可以做个折中,活跃度高的token放内存,一段时间内不活跃的就扔硬盘 |
24
billlee 2015-07-02 16:22:03 +08:00
@xx314327475 这就看你的需求了。如果是长期的会话, 就按照 @q84629462 说的处理。如果是单次使用的会话,我是连续 20 分钟没有通信活动的情况下销毁。
|
25
q84629462 2015-07-02 16:28:00 +08:00 via Android
@billlee app用肯定是长期的了,支付宝app也没有一天不用就要登录一次的变态要求,楼主做的app应该不会比支付宝还危险吧
|
26
BuilderQiu 2015-07-02 16:31:32 +08:00
|
27
glasslion 2015-07-02 16:38:47 +08:00
@xx314327475 有毛不好的。 如果你们的服务器连session也不用的话,倒是没有必要单独为 token去破坏 server 的无状态性 , 既然都用了 session, 把token存内存/redis/数据库里能有啥坏处?
|
28
xx314327475 OP @q84629462 谁说要用明文了?
|
29
xx314327475 OP @hahasong cookie里面保存着 session id,然后通过session id 在服务器找回之前的session,但是session我要让他多久过期好呢?
|
30
xx314327475 OP |
31
garfeildma 2015-07-02 16:47:37 +08:00
建议直接oauth吧,虽然复杂点,但是都有现成的实现,拿来用就好
|
32
xx314327475 OP @billlee 20分钟用户没用就销毁,然后21分钟用户使用了,我让用户重新登陆么?
|
33
hahasong 2015-07-02 16:47:49 +08:00 1
@xx314327475 对,web认证就是这样的。过期时间,那要看你app的设计需求了,如果是强安全的,像银行,证券类,每次放几分钟就超时的就设短一点。如果是聊天社交类的,你可以设一个月或者2周。每请求一次,就重设过期时间
|
34
xx314327475 OP @garfeildma 您说的是oauth 还是 oauth 2.0
|
35
xx314327475 OP @glasslion 问题是session默认生命周期存活多久?
|
36
anubiskong 2015-07-02 16:49:35 +08:00
session存数据库里面, nodejs+mongodb很容易实现, 其他的后端不知道
|
37
xx314327475 OP @hahasong 感谢!
|
38
zjmdp 2015-07-02 16:53:32 +08:00 1
@nisnaker 同意这种做法,用户唯一id可使用设备相关的id,ios的可以使用:[[[UIDevice currentDevice] identifierForVendor] UUIDString]
|
39
hahasong 2015-07-02 16:54:22 +08:00 1
@xx314327475 如果用户量不大,几十万以下的,可以用后台语言自带的session管理,比如php是用文件的形式。如果用户量比较大,对性能要求比较高。就开个redis当永久缓存用。每次放进去的时候设一下过期时间,到期会自动删除。或者用户退出登录就马上删除。业务场景都是这么用的
|
41
xx314327475 OP @nisnaker 😄
|
42
nisnaker 2015-07-02 17:27:45 +08:00 1
@xx314327475 其实你问的问题就是这个token怎么办,如果做成加解密的话服务端就什么都不用存。
至于这个过期时间,就是当前的时间戳减去token里存的时间戳,要不要判定为过期完全在服务器端控制,方便优化。 而且这个多久过期也不用在这里讨论,看你的具体业务,你可以设成1年有效,大不了app跟支付宝一样做下手势验证;或者5分钟过期,过期之后自动再次登录重新获取token以免用户体验太差。 |
44
zyx89513 2015-07-02 19:37:14 +08:00
存在数据库, 用 memcache 缓存. 直接存到 redis 也可以
|
45
zhuangzhuang1988 2015-07-02 19:51:17 +08:00 1
用这个库即可 http://pythonhosted.org/itsdangerous/ 也就是@BuilderQiu 的解决方案, 具体在http://book.douban.com/subject/26274202/ 中第14章有. 另外还可以用于邮件验证
|
46
jedrek 2015-07-02 20:11:50 +08:00 1
@BuilderQiu @nisnaker @hahasong @xx314327475
若认证信息不存储的话,会有些问题。 一个用户有两个设备,在其中一个设备上改掉密码,另一个设备的token如何失效? 换种说法,token泄露了,我改密码后,如何让泄漏后的token失效? |
49
zhujinlong 2015-07-02 21:04:50 +08:00 1
服务端放内存或redis或存db,客户端放headers
|
50
qianlifeng 2015-07-02 21:15:04 +08:00
jsob web token
|
51
qianlifeng 2015-07-02 21:15:15 +08:00 1
json web token http://jwt.io/
|
52
freeznet 2015-07-02 21:18:41 +08:00 1
jwt +1
http://jwt.io |
53
bkmi 2015-07-02 21:36:04 +08:00 1
我们用UUID当token,失效机制大概就像楼上说的,登录重新生成,过期失效,修改密码失效,还有些安全规则失效
|
55
Comdex 2015-07-03 12:39:08 +08:00 1
|
56
aftereclipse 2015-07-03 17:40:12 +08:00 1
token放redis和数据库 登录过程采用https或者自定义的加密方式,返回token+过期时间给客户端 。后续所有api调用都校验token。这样分布式部署应用的时候就无需考虑session问题,所有服务器统一从redis中获取校验token就好了
|