1

What are the best practices for designing a workflow for inviting users to a beta website? This is not for any specific programming language. 2 main requirements are

  1. An interested user can request for an invite using her email
  2. A signed up user can invite others via email (or social media maybe?).

My thoughts:

  1. In case#1, on submit, generate a reversible hash of the email and the timestamp of submission.
  2. Then, send an email with the hash as a query param. When someone clicks on the URL, the controller/router should decrypt the hash and validate the timestamp. If valid, check if the user already exists, else, forward to the sign up page with the email id field pre-populated (or frozen), and allow the user to enter & confirm password and other details.
  3. If the timestamp had expired, send another email to the same user with a new hash.
  4. Case#2, should be exactly similar, but instead of the interested user, an existing user fills up the invitation form, and the email sent to the interested user will have the email or name of the existing user.

Are there any security concerns in this approach? Are there any approaches that would provide a better UX?

1 Answer 1

2

User Experience

In terms of the user experience, you have it down:

  1. User requests invitation
  2. Someone or a process grants the invitation and an e-mail is sent to the user
  3. User clicks a link, is asked to enter sign-up details

For referral sign-ups:

  1. User requests invitation for another user
  2. Other user is automatically granted invitation and sent e-mail
  3. Other user clicks a link, is asked to enter sign-up details

Implementation

In terms of implementation, however, you lost me at "reversible hash".

In short, I'd use a one-time token (arbitrary string) for the invitation validation, and have a table to store the invitations.

The table would look something like:

  • InvitationId - identity
  • Email - string
  • Created - datetime
  • Token - string
  • Expiry - datetime

The two processes are actually quite similar, so I'll cover both pieces together.

1. Invitation request

User enters their e-mail, requesting an invitation, or as an existing user, enters an e-mail for another user.

In either case, this would make a new entry in the invitations table, populating the Email and Created fields.

In the case of an existing user sending an invitation, it would immediately invoke the next part:

2. Granting invitation

When someone or some process decides to grant the invitation, it would do two things:

  • Generate a random token and Expiry date and update the table
  • Send an e-mail containing a sign-up URL with the token

There are many ways to generate a random token, but something simple could be the the sha1 of a Guid, so you end up with something like 1bde8e3ed5709cb399cff0e910442d9b99e181fb.

You'd then send the link as https://mysite.com/signup?token=1bde8e3ed5709cb399cff0e910442d9b99e181fb

3. Signup

The first thing to do, of course, is validate the received token: does it exist and hasn't yet expired?

If everything is good, then you allow the user to sign up, and upon completion, remove the invitation entry.

Additional notes

The token-based approach is much more secure, since it cannot be "cracked". Someone would have to use brute force to guess every possible token, and you could mitigate that by locking the e-mail address for the rest of the sign-up to the one in the invitation.

Keeping this separate from what will eventually be the "non-beta" signup process is also clean in terms of coming out of beta: you should be able to remove this table and related code fairly easily, in contrast to having extra fields stored with the regular user accounts. Think of the token more like a permission to create a new user entry.

I tend to not implement more than is necessary, and not knowing your use case it's hard to speculate on some other things you might want to implement:

  • You may want to keep invitations for some reason (reporting?), so you could use a status field or something similar, and/or date fields indicating the various actions

  • You may wish to re-send e-mails, and so it may be useful to store fields indicating when e-mails were sent (and how many)

  • You may wish to track sign-up source (eg, direct from a URL, or another user) and you could store that in an additional field when you create the invitation entry, and perhaps even transfer it to the account once they sign-up.

3
  • Thanks a lot. I might have overloaded the term hash. The correct term should have been `Symmetric key algorithm', i.e., encrypt the email and timestamp. Use the cipher text as the token in the URL. This would avoid maintaining the table because reporting is a non-issue for me.
    – brayne
    Commented Feb 11, 2014 at 7:01
  • So long as your token contains non-verifiable data, it is security by obscurity ("decrypts successfully? must be legit!"). Don't get me wrong, this may be "good enough" for your case. But to answer your question: it's not all that secure, and there is a better way (as I outlined).
    – gregmac
    Commented Feb 11, 2014 at 7:57
  • Yes. You are correct :)
    – brayne
    Commented Feb 12, 2014 at 6:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.