views:

1277

answers:

6

After user subscribe email to my website. My website will generate an email confirmation and send to them. In the email content, i need to include activation key, something like:

www.domain.com/activate.php?key=$generatedKey

How do you generate the key? using sha1($email)??

After generate the key, i store it in database, so that when user click the link I can verified it with the database?? I am new to it, please advise.. I need an Email Confirmation script..

+3  A: 

Personally, just I use a combination of things like:

$generatedKey = sha1(mt_rand(10000,99999).time().$email);

The chance of collision is small, but I recommend checking your database first before sending it out (using UNIQUE constraints is an easy way).

St. John Johnson
No chance of collision is you add the user ID to the URL as well and check that they both match.
Eli
@Eli, there is a chance, as some collections of characters do hash to the same hash string. Though the chance is quite negligible (but still there).
alex
St. John Johnson
Cool.. after user account activated, should I removed the activate key? If user want unsubscibe, how?
Yes, I would set it up so the activate key only works once. If you need another, generate a fresh one. And alex, I don't think that's relevant here -- we're just using the hash as a random character generator
Eli
+1  A: 
$guid=md5(uniqid(mt_rand(), true));
Itay Moav
+1  A: 

That should do it, however you can improve it by adding some salt, example:

$key = sha1($email . 'doYouLikeSauce');

Other approach is just to generate a random password and send it via email.

Alix Axel
A: 

If you're storing the activation string in the database and checking it later, you don't need a hash at all!

You just need a long, random string. You can generate it however you want, just make it long. In fact, it should ideally have nothing at all do do with the email or username.

Eli
That's why sha1, md5, and other crypt functions are good as they create seemingly random strings. If you want strings that are unique (low collision), your best bet is to base them off of some unique constant (email) and some additional salting.
St. John Johnson
Hash functions don't add any entropy so they don't make collisions any more or less likely in this case. They just *look* more random to us humans.
Eli
A: 

You basically have a few options:

1) Create a single unique identifier that is seemingly random and store it in your database with which username it corresponds to

2) Generate a random password and include the user id and password in the link and store the password in the database

3) Use a one way hashing function (md5, sah1, etc) and a secret identifier to encrypt the user identifier. You don't have to store the encrypted user identifier in your database.

Option 1 is difficult because you have to worry about checking the database to see if the key already exists. However, it is nice that the URL does not contain the username being activated.

If you are already going to use some sort of database to store the user information (probably a password at minimum) in the future, you could go with option 2. It doesn't take a lot to add another column to your database. When sending the email, save the username and something like $key = sha1(rand(1, 99999) . $username) in another column for the row that contains the username. Then have your link look like this: http://you.com/activation.php?user=$username&key=$key. In activation.php you check to see if the key is equal to the value stored in the database.

If you want to use less storage space in your database, option 3 will work. You can use something like $key = sha1($mysecret . $username) as the secret identifier. Use something odd that only you know as $mysecret such as 'aaafj_my_secret_adfaf'. Use the same type of URL as in option 2. However, because you can generate $key based only on $username, you don't need to store it. So when you are processing in activation.php, just check to see if sha1($mysecret . $_GET[username]) == $_GET[key]. If it does, you know you have the correct user. Theoretically, with enough registrations, someone could figure out your value for $mysecret and generate the activation keys too. However, you would surely notice the billions or more of registrations that it would take before they could begin to calculate what it is. The number of activations required is based on the key size of the hashing function. Use sha1 (160 bit) vs md5 (128 bit) to make it harder to guess your $mysecret value.

A: 

$key=base64_encode($_POST['email']);

qburst