我正在一个实现用户身份验证的网站上工作(使用Comeonin和Guardian)。
我正在实施电子邮件验证。我以为我可以利用Guardian中的函数来使用JWT令牌生成url。根据{{3}},这似乎是一个合理的解决方案(只要网址使用https并且令牌在相对较短的时间内到期)。
这是我到目前为止编写的代码:
def email_verification( user = %User{} ) do
if ( user.email != nil ) do
claims = Guardian.Claims.app_claims
|> Map.put("email", user.email)
|> Guardian.Claims.ttl({1, :hours})
{ :ok, jwt, full_claims } = Guardian.encode_and_sign(user, :email_verification, claims)
Zoinks.Mailer.send_verification_email( user.email, jwt )
end
end
我已将电子邮件地址作为索赔。我的想法是,我可以匹配"电子邮件"用户单击链接后,使用数据库中的电子邮件地址声明。
但是,我认为这是一个坏主意 - 特别是因为链接将通过电子邮件显示为明文。
按照这个this post中概述的模式,也许我可以生成一个随机数,哈希(使用Comeonin),将其存储在用户身上并将其作为我的声明代替?这是一个好主意,还是我完全偏离轨道?
假设我让解决方案的这部分工作,是否可以将有效负载类型设置为:email_verification
?
答案 0 :(得分:1)
通过电子邮件发送JWT是完全没问题的,只要使用了很强的秘密(尽管有传输方法,这一点很重要)
引用评论:
我假设如果您收集足够的令牌(通过电子邮件发送明文),那么可能会应用彩虹表攻击等技术吗?
这就是为什么你应该选择一个强烈的秘密。 JWT的最后一部分,即签名,是base64UrlEncode(header)
,base64UrlEncode(payload)
和secret
的组合,放入强大的散列函数,如HMAC SHA256。有关更多安全性信息,请对jwt.io
<强>实施强>
您根本不需要将实际的电子邮件放在索赔中。像email=true
这样的简单字段就足够了,因为您的Serializer已经将用户ID放入令牌中。只需确保用户只能进行一次验证并选择一个强有力的秘密!