Email
验证
自动发送
在用户添加联系方式的时候,自动发送验证邮件,有助于用户体验提高
用户提交联系方式,系统将用户Email地址存入数据库即可
外部程序MessageEamil定时扫描User表:
if(user.Email != empty && //用户填写了Email
user.EmailLastSentTime != empty &&//还没有为该用户发送验证邮件(确保只发送一次)
user.EmailIsActive == false //Email没被激活
(为什么呢?只需要发一次,估计主要是以前页面逻辑复杂之后的问题)
)
{
sendEmail(user.EmailAuthCode);
}
AuthCode在Email发送时生成并存储
重新发送
为什么需要
email服务不稳定,可能因为各种原因,验证email无法到达用户邮箱,所以应该给用户一个机会:重新发送一次邮件
问题
每次重新发送,得“重新组织”邮件内容
能不能把之前的内容存放起来呢?不能
因为:
不知道Email地址是否改变
如果改变了,应该重置AuthCode,避免之前的AuthCode可以用于新的Email
必须保证:重新发送邮件,不能和“提交”之后的自动发送邮件相冲突
方案一
email服务有可能耗时较长,email(前台手工)异步发送,有利于用户体验
但是要在后台做异步发送,发送之后的处理咋办,尤其是当发送出现问题,如何通知用户?非常复杂,放弃了……
方案二
重新发送时:
重置所有之前Email内容(Addresss, IsActive,AuthCode, LastSendTime……)
调用Email验证(生成AuthCode+LastSendTime,发送Email等)
然后,在客户端恢复成“edit=false + email = disabled”状态
这样,/Contact/Edit提交时,会忽略Email的处理
AuthCode
修改Email地址时,AuthCode必须相应更改,否则之前的AuthCode可以用于新的Email
反正是在(自动/手工)发送激活邮件之前,自动生成,并存储在数据库
安全
AuthCode不能用明文保存:
数据库存放被加密后的AuthCode
Email中告知原生的AuthCode
激活页面将url中原生的AuthCode加密后和数据库值比较
AuthCode可以用明文保存
因为验证邮箱首先需要用户登录
在Email被激活时,清空原AuthCode
为了防止用户修改Email后验证码被新Email重用(因为目前并激活链接中没有Email地址)
判断Email的Status,见:GetStatus()
AuthCode为空,不能激活
激活
方案一(采用)
激活码为明文,需登录后才能激活
优点:安全
确定:用户使用稍有不便
方案二
不需要登录就可以激活
优点:方便
缺点:
激活链接要带着用户Id
不是很安全(比如发到错误邮箱的链接,也可以被点击后激活)
/Contact/Edit中的Email修改
复杂的原因
前后台交互
前台向后台传值时仅能传递EamilAdress,不能传递AuthCode等。
所以,如果用AutoMap直接覆盖,会导致AuthCode等数据丢失
后台难以判断用户的目的,比如:
后台得到的EmailAdress为空,是需要:
删除,还是
不处理
这需要结合“修改”的checkbox进行判断
后台本身
后台需要将前台传入的EmailAdress和数据库中已有的值进行比较
变化时才处理
EamilAdress变化时,其对应的AuthCode等应随之变化
利用数据库中的数据,比照前台传入数据(EmailAddress和Checkbox的值)
方案
首先,根据Edit(checkbox)的值做第一个分支
NULL(之前没填写Email)
有值:新建
无值:不处理
true(前台告诉后台:要改)
比较email的值是否
真的改了:
覆盖
实际上没改:
不处理
false(前台告诉后台:别动)
忽略
数据库中没值
前台没值:不做任何处理(=覆盖)
前台有值:添加(=覆盖)
数据库中有值
[前台规则:只要数据库中有值,就会禁用掉Email?]
前台没值:
edit=false(前台被禁用)
不处理 ,因为这表明:
邮件已激活,所以用户不处理
邮件未激活
用户也不处理,或者
重新发送 (不区分原Address修改后)
edit==true
|| checkbox=null
(用户主动删除)
所以:删除(=覆盖)
前台有值(edit==true):
相同:不处理(≠覆盖)
不同:覆盖
名词解释
覆盖:
数据库中只有EmailAdress,其他字段被清空(因为:前台不会传回其他字段)。,同新添加的Email一样,等待外部程序扫描发送验证Email
不处理:
EmailAdress不变,也保留了数据库中的AuthCode等其他字段信息
Email发送失败
如果发送成功,一定就没error吗?
首次发送,肯定是的
以前有error,再次发送会清空error吗? 必须的
用户重新验证Email
管理员检查
MessageEmail.exe绝不能重复发送已发送过一遍的Email
是Error和LastSendTime结合判断EmailStatus好呢?还是单独一个字段?
结合:数据无冗余
单独:看似清晰,实际麻烦