Reputation: 4341
I'm working on a site that implements user authentication (using Comeonin and 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. 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).
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? 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
?
Upvotes: 3
Views: 738
Reputation: 1364
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)
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. For more security infos, there is a good description on 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. Just make sure a user can only be verified once and pick a strong secret!
Upvotes: 1