对你们大多数人来说,这是一个很常见的主题。我正在用Java构建一个webapp,使用Spring + Spring Security + Hibernate + MySQL +等......
我正在实施“重置密码”模块。我已经知道了流程,并拥有所有表格和相应的控制器。我只是想知道,在编写代码之前,如果我从右脚开始然后继续改进它。
MySQL表格:
PASSWORD_CHANGE_REQUESTS (
TOKEN VARCHAR(126) NOT NULL,
USERNAME VARCHAR(50) NOT NULL,
CREATION_TIME DATETIME NOT NULL,
PRIMARY KEY(TOKEN)
)
我看过一些帖子推荐EXPIRE_DATE字段。这真的值得吗?
唯一标记:
我使用带有用户名+时间戳的Spring SHA编码器作为参数(+所需的盐值),它返回字符串,如: 92c303b9740da5959418c32d04b6ec6f4ca61637 。
此方法是否真的为网址生成唯一标记?或者有更好的方法吗?
在Java中,时间戳的生成如下:
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy h:mm:ss");
String timestamp = sdf.format(date);
答案 0 :(得分:2)
我说将字段EXPIRE_DATE添加到DB。 1 - 为方便起见,您可能需要EXPIRE_DATE字段,以便在根据数据库中的值验证和验证令牌时,一次性执行选择并检查有效性。 2 - 对于数据库清理,您可以通过简单地运行脚本来轻松截断过期记录。
您还可以通过检查当前时间来验证令牌在应用程序层中是否已过期,但这似乎更麻烦。数据库清理还取决于某些应用程序逻辑或脚本逻辑,以确定记录是否已过期并准备好删除。
Spring HSA编码器应该可以用于您的目的,但它的用途主要是编码密码而不是生成唯一的令牌。对于唯一令牌,您可以查看Java UUID
你可以在这里阅读更多内容
How to generate a random alpha-numeric string?
和
答案 1 :(得分:1)
如果黑客获得对用户电子邮件的控制并找到其中一个链接,则密码更改请求的到期非常有用。如果用户不再使用该系统的电子邮件帐户,至少它会保护他们免于在系统中重置密码,因为请求可能已过期。显然,如果他们获得了对您系统使用的电子邮件帐户的控制权,则到期时间不会太大,因为他们可以简单地再次请求重置。无论哪种方式,您都可以采取相对简单的措施为用户提供额外的安全保障。
在生成唯一令牌方面,我认为您的策略非常好。为了使生成冲突令牌变得更加困难,您可以使用System.nanoTime()
或System.currentTimeMillis()
之类的内容来获得更精确的时间。您当前的方法意味着如果在同一秒内调用它,您将获得一个非唯一令牌。虽然这可能很少见,但毫秒或纳秒却更为明显。