使用 Guardian 创建电子邮件验证 URL

Posted

技术标签:

【中文标题】使用 Guardian 创建电子邮件验证 URL【英文标题】:Create email verification url using Guardian 【发布时间】:2017-01-20 00:59:08 【问题描述】:

我正在开发一个实现用户身份验证的网站(使用 Comeonin 和 Guardian)。

我正在实施电子邮件验证。我想我可以利用 Guardian 中的功能来使用 JWT 令牌生成 url。根据this post,这似乎是一个合理的解决方案(只要 url 使用 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

我已将电子邮件地址作为声明放入。这个想法是,一旦用户单击链接,我就可以将“电子邮件”声明与数据库中的电子邮件地址相匹配。

但是,我认为这是一个坏主意 - 特别是因为链接将通过电子邮件以明文形式公开。

按照SO post 中概述的模式,也许我可以生成一个随机数,将其散列(使用 Comeonin),将其存储在用户面前并将其作为我的声明?这是个好主意,还是我完全偏离了轨道?

假设我让这部分解决方案正常工作,是否可以将有效负载类型设置为:email_verification

【问题讨论】:

However, I'm assuming that this is a bad idea - especially since the link will be exposed as clear text via email. 到底是什么意思?如果您使用强机密,则使用您的方法 AFAIK 应该没有问题 老实说,我不确定 - 我在安全方面缺乏经验 我假设如果你收集了足够多的令牌(通过电子邮件的明文),那么就有可能应用彩虹表攻击等技术?如果电子邮件中令牌的安全性受到威胁,那么网站也是如此 - 因为它使用相同的配置 【参考方案1】:

通过电子邮件发送 JWT 完全没问题,只要使用强机密(但这始终很重要,尽管使用了传输方法)

来自 cmets 的引述:

我假设如果您收集到足够多的令牌(通过电子邮件发送明文),那么就有可能应用彩虹表攻击等技术?

这就是为什么你应该选择一个强大的秘密。 JWT 的最后一部分,即签名,是 base64UrlEncode(header)base64UrlEncode(payload)secret 的组合,放入像 HMAC SHA256 这样的强哈希函数中。更多安全信息,jwt.io上有很好的描述

实施

您根本不需要将实际电子邮件放入声明中。像 email=true 这样的简单字段就足够了,因为您的序列化程序已经将用户 ID 放入令牌中。只需确保用户只能被验证一次并选择一个强大的秘密!

【讨论】:

如果我允许用​​户随时更改他们的电子邮件地址(即甚至在用户单击激活链接之前) - 我不需要确认网络令牌用于电子邮件地址数据库? 是的,如果您想支持为单个用户验证不同的电子邮件,那么将电子邮件存储在令牌中是正确的方法!我的想法只是初步的单一电子邮件验证。

以上是关于使用 Guardian 创建电子邮件验证 URL的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.4 Auth Guardian 驱动程序 [customers] 未定义

如何在没有?authuser = 1的情况下获得经过身份验证的GCS URL

使用 django-guardian 进行基于角色的访问

使用 Django 和 django-guardian 对象权限的每个对象的组

PHPMailer 使用 SMTP 身份验证发送电子邮件,但 Gmail 仍然声称它无法验证发件人

vmware虚拟机克隆提示操作已超时