简体   繁体   English

使用Guardian创建电子邮件验证网址

[英]Create email verification url using Guardian

I'm working on a site that implements user authentication (using Comeonin and Guardian). 我正在开发一个实现用户身份验证的网站(使用Comeonin和Guardian)。

I'm in the process of implementing email verification. 我正在实施电子邮件验证。 I thought that I might take advantage of the functions in Guardian to generate the url using a JWT token. 我以为我可以利用Guardian中的函数来使用JWT令牌生成url。 As per this post , this seems like a plausible solution (as long as the url uses https and the token expires in a relatively short period of time). 根据这篇文章 ,这似乎是一个似是而非的解决方案(只要网址使用https并且令牌在相对较短的时间内到期)。

Here's the code I've written so far: 这是我到目前为止编写的代码:

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

I have put the email address in as a claim. 我已将电子邮件地址作为索赔。 The idea being that I could match the "email" claim with the email address in the database, once the user clicks the link. 我的想法是,一旦用户点击链接,我就可以将“电子邮件”声明与数据库中的电子邮件地址相匹配。

However, I'm assuming that this is a bad idea - especially since the link will be exposed as clear text via email. 但是,我认为这是一个坏主意 - 特别是因为链接将通过电子邮件显示为明文。

Following the pattern outlined in this SO post , maybe I could generate a random number, hash it (using Comeonin), store it against the user and put that in as my claim instead? 按照这篇SO帖子中概述的模式,也许我可以生成一个随机数,哈希(使用Comeonin),将其存储在用户身上并将其作为我的主张代替? Is this a good idea, or am I completely off-track? 这是个好主意,还是我完全偏离轨道?

Assuming that I get this part of the solution working, is it okay to set the payload type to :email_verification ? 假设我将解决方案的这部分工作,是否可以将有效负载类型设置为:email_verification

Sending a JWT via e-mail is completely fine, as long a strong secret is used (but that's always important, despite the transport method) 通过电子邮件发送JWT是完全没问题的,只要使用一个强密码(但这一点很重要,尽管有传输方法)

Quote from the comments: 引用评论:

I'm assuming that if you collect enough tokens (clear text via email), then it might be possible to apply a technique such as a Rainbow Table attack? 我假设如果你收集足够的令牌(通过电子邮件发送明文),那么有可能应用一种技术,如彩虹表攻击?

That's why you should pick a strong secret. 这就是为什么你应该选择一个强烈的秘密。 The last part of the JWT, the signature, is a combination of base64UrlEncode(header) , base64UrlEncode(payload) and secret put into a strong hashing function like HMAC SHA256. JWT的最后一部分,即签名,是base64UrlEncode(header)base64UrlEncode(payload)secret放入强大的散列函数(如HMAC SHA256)的组合。 For more security infos, there is a good description on jwt.io 有关更多安全信息,请参阅jwt.io

Implementation 履行

You don't need to put the actual email inside the claims at all. 您根本不需要将实际的电子邮件放在声明中。 A simple field like email=true should be enough, since your Serializer already puts the user id into the token. email=true这样的简单字段就足够了,因为你的Serializer已经将用户id放入了令牌中。 Just make sure a user can only be verified once and pick a strong secret! 只需确保用户只能进行一次验证并选择一个强有力的秘密!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM