
|
View Full Version : Verifying a user's email - I'm bamboozled!
jonathanbull 09-28-2004, 10:51 AM Hi there,
As some of you may know, I'm using a registration script which stores data to a flat file. I've received a lot of help from kind people on WHT, perhaps someone could give me a bit of help again!
Currently, the user that has registered receives an email with their user details. I would like to include a 'to verify your email address, please click this link', and once this has been clicked the account will become active.
I've got no idea how to even begin coding this. I feel I could give it a go if I knew the logistics of how such a thing works, but unfortunately when I googled it I just receive loads of help on checking the email is in a valid format!
If anybody could point me in the right direction or enlighten me on how such a wonderful thing works I'd be extremely grateful!
Many thanks in advance,
Jon. :)
Burhan 09-28-2004, 11:11 AM Usually what happens is there is a flag in the user table that's set to "yes" or some other value if the user requires approval.
Then, a random code is generated that is stored in another table along with the user's id. This is the code that is given in the email, usually in the form of a link such as verify.php?code=5434xiufdk334 or some such.
Then, its just a matter of comparing the code with the user record, if it matches, then the user's database record is updated to remove the "pending" flag and the user is verified.
That's the basic idea, to which you can expand and add all sorts of goodies such as a timeline (codes are only valid for X number of days), etc.
Perhaps the most difficult bit in all of this is coming up with the code, so I'll help you out in that area by writing a small function that can give you random strings:
<?php
function randKeyGen($len = 8)
{
return strtolower(substr(md5(uniqid(time(),true),0,$len));
}
?>
jmaskell 09-28-2004, 11:13 AM eregi ("^[[:alnum:]][a-z0-9_.-]*@[a-z0-9.-]+\.[a-z]{2,4}$", stripslashes(trim($_POST['email']))
The following will check that what has been entered in the field named "email" is actually an email address, not a random text inputted by someone. It won't check that the email address actually exists, you'd have to use verification like forums can use when people sign up for that.
jonathanbull 09-28-2004, 03:17 PM Originally posted by fyrestrtr
Perhaps the most difficult bit in all of this is coming up with the code, so I'll help you out in that area by writing a small function that can give you random strings:
<?php
function randKeyGen($len = 8)
{
return strtolower(substr(md5(uniqid(time(),true),0,$len));
}
?>
Thank you very much for your help.
Does this not need to be defined in a $variable and then called upon by the script? How could I adapt this to do so?
When you execute the function it'll return a random string so if you need it as a variable just define it like:
$string = randKeyGen();
jonathanbull 09-28-2004, 03:59 PM Originally posted by Loon
When you execute the function it'll return a random string so if you need it as a variable just define it like:
$string = randKeyGen();
Thanks for this.
I added
function randKeyGen($len = 8)
{
return strtolower(substr(md5(uniqid(time(),true),0,$len));
}
to my script, and then added this in my strings
$key = randKeyGen();
Now the page won't load. I expect I've made a big mistake!
sea otter 09-28-2004, 04:37 PM The parens are off in your return statement; you have 5 left and 4 right.
Both md5 and uniqueid take an optional bool, so I'm not sure where your other right paren should go.
jonathanbull 09-28-2004, 05:05 PM Originally posted by sea otter
The parens are off in your return statement; you have 5 left and 4 right.
Both md5 and uniqueid take an optional bool, so I'm not sure where your other right paren should go.
Thanks sea otter. Could you please tell me what this part of the script means, it would help me figure it out. :)
return strtolower(substr(md5(uniqid(time(),true),0,$len));
Thanks again!
sea otter 09-28-2004, 06:22 PM Originally posted by jonathanbull
Thanks sea otter. Could you please tell me what this part of the script means, it would help me figure it out. :)
return strtolower(substr(md5(uniqid(time(),true),0,$len));
Thanks again!
As fyrestrtr said in his original post of the code, it generates a unique ID as a string.
But as to where the missing parenthesis goes...
*runs off to the php manual*
missing paren fixed:
return strtolower(substr(md5(uniqid(time(),true)),0,$len));
Tried it and verified that it works. Kudos to fyrestrtr, it's a cool function; it's going in my bag o' snippets!
Burhan 09-29-2004, 01:53 AM Yeah, sorry for the typo. Great that others caught it and were able to help. There are other ways of generating more "random" strings, but they are overkill for this project.
A bit more explanation on what the function does, splitting it up into its components:
uniqid(time(),true)
This is a function that returns a unique id based on a prefix. If there is no prefix, then the string returned is 13 characters long. If you specify the optional second parameter as true, the string returned is 23 characters. You can give the first parameter (called the prefix) as any known value; but I chose time() because its (almost) guaranteed to be unique. Another good candidate is rand().
Next, we take an md5 hash of the returned id, which adds additional randomness to our value.
Finally, two cleanup functions. substr() to trim our returned value to the specified length (defaults to 8), and then strtolower to convert the returned 8 character random string into lowercase.
Here is actually what is happening in that one line return statement:
$id = uniqid(time(),true);
$hash = md5($id);
$trimmed = substr($hash,0,$len);
$lowered = strtolower($trimmed);
return $lowered;
I just compressed it into one line.
jonathanbull 10-01-2004, 05:41 PM This all works perfectly.
Many many thanks go to fyrestrtr, PrimeHosting, Loon and sea otter. I don't know what I'd do without you!
I changed it to generate a 30 character string. I then placed this in the 'confirm email', in the format of
[url]http://domain.com/user/verify?code=*string*
I then created the verify page, using this coding:
;
if($randomstr){
echo "$randomstr";
}
?>
This echo's the string perfectly, but then I got stuck :stickout:
What I would like it to do is find the string in my text file, and if it is found the string will be replaced with the word 'yes'.
If anybody could point me in the right direction I'd be most grateful.
Thanks again for all your help so far. Hopefully, I'm not using the word 'string' incorrectly as well......!
sea otter 10-02-2004, 12:08 AM Originally posted by jonathanbull
What I would like it to do is find the string in my text file, and if it is found the string will be replaced with the word 'yes'.
[/B]
Let me see if I get this. Youv'e got a text file with something like:
ad09s3209823adfd
lkj3423ljlkasfd235j
dfsmcs90k4mf43wd
where each line is a 30-character unique string. Is that correct? And then you want to see if a particular string is in that file. Is that correct? If that's the case, here's how to do it:
function keyExists($filename, $key)
{
$found = false;
$file = fopen($filename,'r');
while (!feof($file)) {
$line = rtrim(fgets($file));
if ($key == $line) {
$found = true;
break;
}
}
fclose($file);
return $found;
}
// and to use it:
if (keyExists('keys.txt','akasd878dfgDJu809dkd'))
echo "found key";
else
echo "key not found";
Burhan 10-02-2004, 01:42 AM Easier (different way):
<?php
$keys = file("keys.txt");
if (in_array($_GET['key'],$keys))
{
// -- key is valid
} else {
// -- invalid key
}
?>
jonathanbull 10-02-2004, 09:05 AM Many thanks for your replys.
I tried this:
<?php
$key = $_GET[code];
$filename = file('test.txt');
function keyExists($filename, $key)
{
$found = false;
$file = fopen($filename,'r');
while (!feof($file)) {
$line = rtrim(fgets($file));
if ($key == $line) {
$found = true;
break;
}
}
fclose($file);
return $found;
}
// and to use it:
if (keyExists('test.txt','akasd878dfgDJu809dkd'))
echo "found key";
else
echo "key not found";
?>
I probably did not explain myself well enough in my original post. The file it is opening has many values all|seperated|by|pipes.
Regardless of this, I created a file which just the keys in called test.txt I defined this at the top of the script - I've probably done that drastically wrong! Anyway, when I ran the script I always got the 'code not found' message, even though the key was in the file. I also had to define the $key to be the code= from the address bar and still no luck, I'm really confused now!
Thanks for helping such a newbie :)
Jon.
Burhan 10-02-2004, 09:49 AM You meshed the two codes -- which will not work well.
If your test.txt file is something like this
31435451|3434354dferef|gsgtrwtwrt4545
afq43qqeff|aer433reqr|qer43r1rer
Each key separated by | and any number of keys on each line, then you can use this function:
<?php
function keyExists($filename,$keytocheck)
{
if (!($contents = file($filename)))
{
die("Cannot open $filename");
}
foreach($contents as $line)
{
$keys[] = explode("|",$line);
}
if (in_array($keytocheck,$keys))
{
return true;
} else {
return false;
}
}
?>
Use it like you have been doing :
if (keyExists('test.txt','akasd878dfgDJu809dkd'))
echo "found key";
else
echo "key not found";
jonathanbull 10-02-2004, 09:58 AM Thanks again fyrestrtr.
The values in my text file which are seperated by | are not all keys. Each line is created with information about a user, e.g:
username|dateregistered|key
I would like the script to search through test.txt and if the key in the address bar (code=) is found, it will be replaced by the word 'yes'.
Will this part:
if (keyExists('test.txt','akasd878dfgDJu809dkd'))
echo "found key";
else
echo "key not found";
be placed at the bottom of this part?:
<?php
function keyExists($filename,$keytocheck)
{
if (!($contents = file($filename)))
{
die("Cannot open $filename");
}
foreach($contents as $line)
{
$keys[] = explode("|",$line);
}
if (in_array($keytocheck,$keys))
{
return true;
} else {
return false;
}
}
?>
Many thanks again for your help.
Burhan 10-02-2004, 10:12 AM Ah, then you need this function :
function keyExists($filename,$keytocheck)
{
if (!($contents = file($filename)))
{
die("Cannot open $filename");
}
foreach($contents as $line)
{
$temp = explode("|",$line);
$keys[] = $temp[2];
}
if (in_array($keytocheck,$keys))
{
return true;
} else {
return false;
}
}
This will check if a given key exists in the file. Now, to replace that key with yes -- takes a bit more work ;)
This bottom code does the checking+replacing in one swoop:
(Use the code below by itself -- without the function on top -- or use the function on top, and then write your own file editing code)
<?php
//Read all lines in the file, and stick them in an array
$contents = file("test.txt");
//Step through the array and
//check if the given key exists
foreach($contents as $line_number => $line)
{
//Split each line on the |
$temp = explode("|",$line);
//The third entry in the $temp array is the
//key -- so we compare it with the key given
if ($temp[2] == $_GET['key'])
{
//matches, so we replace the key with
//yes for this user
$temp[2] = "yes";
//Update the line in our array
$contents[$line_number] = implode("|",$temp);
echo "Key found!";
} else {
echo "Key not found!";
}
}
//Now we have to write the new information back to the file
if(!$fp = fopen("test.txt","w"))
{
die("Cannot open test.txt for writing. Check permissions");
}
//write the new file -- with updated information
fwrite($fp,implode("\n",$contents));
//close the file
fclose($fp);
?>
jonathanbull 10-02-2004, 11:09 AM Thanks so much for your help fyrestrtr, I really cannot express how grateful I am of this.
I used the second code you gave which does the checking and replacing in one swoop, I didn't change anything.
Now, when I load the page domain.com/verification.php?code=5d146bdb29abdb586e0b37ccc23de3 I get the 'Key Found!' message.
I thought great, it works. I then changed some of the characters in the address bar and refreshed, realising that I get 'Key Found' no matter what the code in the address bar is. I then opened up test.txt and found that it had done this:
username|5c146bdb29gdfb586e0b37ccc23de3|yes
I then realised that no matter what code was here, yes was always added onto the end!
I'm sure I've done something wrong. Maybe it's what I haven't done, although I couldn't find any variables which I had to change.
jonathanbull 10-02-2004, 11:35 AM After printing off and studying the code, I realised I had to change the word 'key' to the word 'code'.
It works perfectly now! Thank you ever so much for all your help.
jonathanbull 10-02-2004, 07:23 PM Me again!
I've been testing this PHP script all night and all's well, apart from one small problem I'm having.
If the key is in the last line like this:
user|pass|yes
user|pass|yes
user|pass|yes
user|pass|randomkey
then 'random key' is changed to the word 'yes'.
but, if the key is not on the last line like this:
user|pass|yes
user|pass|randomkey
user|pass|yes
user|pass|yes
then 'random key' is not found. I spent a long time fiddling about with the code but nothing seemed to work. I expect there's an easy solution!
|