NotionCommotion Posted February 13, 2015 Share Posted February 13, 2015 An email is sent to the user which contains a link with an ID which identifies the recipient of the email plus the nature of the message conveyed.The user clicks the link on the email, and a page is displayed which displays the user's identity plus details of the message based on the ID. A link is included on the page which performs one (and only one) of the following three tasks: If the user is logged on (as determined by a session), an edit page is displayed which allows the user to modify data pertaining to the message. If the user (as determined by something in the link) is not logged on but they have previously set up a password, a username/password form is displayed to allow them to log on. Upon logging on, they will be sent to the aforementioned edit page, however, I have this part handled. If the user is not logged and they have never set up a password, a form is displayed presetting their username which allows them to set their password. I know I "could" just sent them to the normal logon page (task 2), but don't like this approach from a ux prospective. Upon completing the form, I will probably return them to the logon page instead of automatically logging them on, but that is a different story. My question relates to the third task. Obviously, I can't use some weak ID which makes it easy to find forms which allow passwords to be set. Is this approach acceptable providing that I use a strong random ID? Should the ID be the same ID as used on the originating email? Any other thoughts on how to implement this? Thank you Quote Link to comment Share on other sites More sharing options...
kicken Posted February 13, 2015 Share Posted February 13, 2015 The third case is basically the same as how you'd handle a "Forgot Password?" page. You generate a random token and send it to them, then store the hash of that token in your database. Give it a limited duration and make it one-time use and that's about it. So long as you use a strong randomness source and a decent size sample size then you're fine. For my verification tokens I pull 12 bytes from the system's random source. The random bytes are the encoded using Crockford's Base-32 to create the token value. The tokens may seem a bit long but since most users will just click the link it the email, or copy-paste the value I don't see it as being a problem. I always provide the token in the email's both as a link that can be clicked/copy-n-pasted and as an individual item so they can copy just the token if need be. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted February 13, 2015 Author Share Posted February 13, 2015 Thanks Kicken, Yes, I suppose it is the same as the "Forgot Password" routine. I'll probably, however, wish to increase the duration due to the nature of the business request. I am creating my tokens using the following. Seem random enough? $token=bin2hex(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)); At times, I've attempted to make them more human friendly using the following. Is Crockford's Base-32 better? Is there an easy way to implement it? $encoder = new Base2n(5, '0123456789ABCDEFGHJKMNPQRSTVWXYZ'); $token = $encoder->encode($token); In regards to allowing the user to copy the token, do you ask them to copy the link and put it in their browser, or copy just the token and input it in a form? Thank you Quote Link to comment Share on other sites More sharing options...
kicken Posted February 13, 2015 Share Posted February 13, 2015 (edited) At times, I've attempted to make them more human friendly using the following. Is Crockford's Base-32 better? Is there an easy way to implement it?What you have basically is Crockford's Base-32. His version just excludes commonly confused letters and 'U' to prevent accidental obscenity which is what you appear to do as well. I use the eloquent/encdec package to do the base-32 encoding and wrote an encode/decode class for it that implements crockford's alphabet. In regards to allowing the user to copy the token, do you ask them to copy the link and put it in their browser, or copy just the token and input it in a form? They can do both. The email I send out is worded roughly as: To verify your email address and continue your registration, please click or copy-and-paste into your browser the link below. http://example.com/verify-email/1234/QA90ZCTJN30RCTZ4 Your verification code is: *QA90ZCTJN30RCTZ4* Following the link will complete the verification process. Going to http://example.com/verify-email/1234 presents a form that asks for the token and also a button they can use to generate and send a new token. After I send the initial token I redirect them to the form that asks for the token. In the form that asks for the token I apply the text-transform: uppercase; style to the input box so that as they type the code it will appear in upper-case automatically. I surround the token in the email with *'s because that is a common convention for emphasizing text and some plain-text mail clients will bold-face that text as a result. I make sure that I trim() the *'s and spaces just incase they accidentally copy/paste those along with the token. Edited February 13, 2015 by kicken Quote Link to comment Share on other sites More sharing options...
scootstah Posted February 13, 2015 Share Posted February 13, 2015 I am creating my tokens using the following. Seem random enough? I usually use openssl_random_pseudo_bytes(). $token = bin2hex(openssl_random_pseudo_bytes($length = 60)); Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.