关于帐号激活邮件的设计

2014-02-18 14:11:38 +08:00
 jayn1985
这两天闲暇时在写一个小应用,遇到了用户注册后,发送激活邮件给用户用以激活帐号的设计问题。
我目前的想法是这样的:在激活链接中传递三个参数,用户的email,发送此邮件时的时间戳ts,以及一个MD5加密后的字符串token(通过md5(secret, email, ts)得出),这样的话,用户在点击这个link后,服务器端获取相关的参数,首先校验token的有效性,通过md5(secret, 传过来的email地址,传过来的ts)与传过来的token比较,这样可以避免用户伪造ts和email;接着判断当前时间和ts的时间差是否满足一个合理的间隔(例如48h),如果一切都OK,那么就将用户设置为激活状态
这种方法目前来看基本可以满足我的需求(至于是否健壮还望各位大大指教),但是这样的话激活link就会比较长,因为需要传送3个参数进去,我参考了下很多网站发送的激活邮件,有类似我这种格式的链接,也有的非常的简短,比如V2EX网站,其激活链接格式为: http://www.v2ex.com/activate/XXXXXXXX,所以我很好奇这种方式一般都是怎么校验的呢,难道需要在用户表中新增一个字段用来保存这个字符串,然后验证的时候只要比较下即可?那这种方式代价是不是高了些?所以恳请各位大大都来介绍下你们都是如何设计这个功能的?多谢~
6107 次点击
所在节点    Python
31 条回复
loading
2014-02-18 14:17:34 +08:00
邮件里连接直接点,谁管长不长。

btw:你md5每次都算啊…不也存起来吗?
wingoo
2014-02-18 14:18:20 +08:00
新增一个验证表, 主键为guid, 其他字段可以为user_id, 过期时间等
jayn1985
2014-02-18 14:41:28 +08:00
@loading 你说每次都需要计算MD5,原因是如果用户更改了link中的email或者ts,那你在server端仍然需要计算一下当前计算出的MD5值和传来的token值是否匹配吧,否则你怎么验证用户没有更改你的激活链接呢?
justfindu
2014-02-18 14:53:46 +08:00
@jayn1985 验证email和token search一下sql ,带上token过期时间的条件 没有就说明不是正确用户
lichao
2014-02-18 14:56:01 +08:00
我觉得只需一个 token 就行,其它的都多余
jayn1985
2014-02-18 15:05:45 +08:00
@lichao 那server端是如何做验证的呢?求详细解答,多谢:)
lichao
2014-02-18 15:07:31 +08:00
@jayn1985 你 server 端,有个表,根据这个唯一的 token,即可确定是哪个用户了,然后。。。。。。
jayn1985
2014-02-18 15:12:58 +08:00
@lichao 你的意思是加张表或者是在User表里面加个字段存这个token么?那用户激活成功了的话,这个信息之后还有用么?如果没有用的话,这样设计是不是代价高了些?
lichao
2014-02-18 15:17:43 +08:00
@jayn1985 自然是放另外一个表。嗯,弊端就是这个信息之后就没用了
dorentus
2014-02-18 15:19:57 +08:00
单独加张表放 token,用完删。怕慢就用 redis 之类的存。

这个代价不高的;等你在这个地方遇到瓶颈的时候,你的系统的其它部分估计都已经遇到过 n 次瓶颈、重写多遍了……
jayn1985
2014-02-18 15:27:36 +08:00
@lichao 我在网上搜了相关文章,很多也都是类似你这样的设计,我很想知道这种设计的原因,是因为很难构造出一个健壮的方式来避免安全问题么?抱歉想得太多,呵呵~
vob636
2014-02-18 15:37:24 +08:00
@dorentus +1用完肯定删……@jayn1985 楼上的已经很健壮了……各种token了……是在不行,你加上https……
jayn1985
2014-02-18 15:42:11 +08:00
@dorentus 感谢回复,加表后对其操作确实代价不大,但是我总觉得因为这么一个不算大的feature而要新增一张表,这个有点“杀鸡用牛刀”的感觉:)也许在不新增新的实体的前提下,来做这个email校验确实没有完全周到的想法(我自己设想的方法可能确实有漏洞,但是不是做安全出身的所以目前还没看出来。。)
lichao
2014-02-18 15:45:55 +08:00
@jayn1985 @jayn1985 我只是觉得这种方式最简单有效,安全性方面也没有缺陷
family
2014-02-18 15:46:16 +08:00
直接加字段或表 有时间纠结的功夫多达游戏
jayn1985
2014-02-18 15:49:59 +08:00
@family 哈哈:)
jayn1985
2014-02-18 15:51:05 +08:00
@lichao 呵呵,是的,还是很感谢回复啊:)
ksc010
2014-02-18 16:10:11 +08:00
突然想到一个问题,把点击放到email中
QQ这样的邮件服务商会不会为了安全原因访问这个url?
目前看来来应该没有这种情况
ksc010
2014-02-18 16:13:22 +08:00
也可以放到session
但是有个问题会话结束后 链接就失效了
换个浏览器也不行
cevincheung
2014-02-19 01:05:02 +08:00
你的方案完全可以啊。连接直接点就是的。不用管长度。参考一下其他厂商的邮件范本就 可以了嘛。

http://domain.com/verify?email=x&ts=x&sign=x

服务端保存一个公共密钥。这样sign的值也根本不需要保存。ts可以用来判断连接是否过期,而且这个过期时间可以自己随意控制。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/100736

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX