Email verification using tokens – CakePHP

Web & Code 16 Comments

I recently wrote a code for an email verification system using cakephp. Well, before you use it there are few things. This is written by a cake noob so may not be the best there is. I have not written it as a general stand alone piece of code. So its need modifications for use. And I am a sucker when it comes to commenting and formatting my code so please dont mind. My thanks to Edward and the CakePhP Google Groups. And finally cake rocks!!!


Database Table

A basic user table with the following columns

id - primary key and auto increment
activate *

*columns with which we are concerned with

Controller code

class UsersController extends AppController {
var $name = 'Users';
var $helpers = array('Html', 'Form');
var $components = array('Email');
function register() {
if (!empty($this->data)) {
$this->User->data = $this->data;
//Create Token using form data and random number to ensure its unique and cannot be replicated
if ( $this->User->validates()) {
//Save all form data including the tokenhash
$ms='Click on the link below to complete registration ';
//create mail body
$this->Email->from = 'yourName <email>';
$this->Email->subject = 'Confirm Registration for Niwiki - reg.';
//send mail
$this->Session->setFlash('Please Check your email for validation Link');

function verify(){
	//check if the token is valid
	if (!empty($this->passedArgs['n']) && !empty($this->passedArgs['t'])){
$name = $this->passedArgs['n'];
$tokenhash = $this->passedArgs['t'];
$results = $this->User->findByUsername($name);
//check if the user is already activated
	if ($results['User']['activate']==0){
	//check the token
//Set activate to 1
	//Save the data
$this->Session->setFlash('Your registration is complete');
$this->Session->setFlash('Your registration failed please try again');
else {
$this->Session->setFlash('Token has alredy been used');
$this->Session->setFlash('Token corrupted. Please re-register');
$this->Session->setFlash('Token corrupted. Please re-register');
function login() {
if (!empty($this->data)) {
if ( $this->User->validates()) {
	$this->User->data = $this->data;
	$results = $this->User->findByEmail($this->data['User']['email']);
	//find the user based on the data from your login form
	if ($results['User']['activate']==1)
	//check if his activation is set to 1 by the verify function
	// check if the passwords match
	if ($results && $results['User']['password'] == md5($this->data['User']['password'])) {
	$this->Session->write('User', $results['User']);
	//logged in
	} else {
	$this->Session->setFlash('Invalid Username or Password please try again');
  else  {
	$this->Session->setFlash('Your Email is not verified. Please verify and try again.');

Model Code

class User extends AppModel {
var $name = 'User';
var $validate = array(

Views – register.ctp

<?php echo $form->create(null, array('url' => '/users/register'));?>
<h2> Fill out the form below to register </h2>
<?php echo $form->input('User.username') ?>
<?php echo $form->input('User.password',array('size' => '30',)) ?>
<?php echo $form->input('User.confirmpassword', array('size' => '30','type'=>'password',)) ?>
<?php echo $form->input('') ?>
<?php echo $form->Submit('register') ?>
<?php echo $form->end(); ?>

Views – login.ctp

<?php echo $form->create(null, array('url'=>'/users/login'));?>
<h2>Please log in.</h2>
<?php echo $form->input('') ?>
<?php echo $form->input('User.password') ?>
<?php echo $form->submit('login') ?>
<?php echo $form->error('', $login_error) ?>
<?php echo $form->end(); ?> 

16 Responses to “Email verification using tokens – CakePHP”

  1. Tri Bui Says:
    May 8th, 2009 at 5:37 am


    Good job. I have done something 95% similar. The only thing I did extra was this:

    When I generated the token, I appended the unix timestamp to the SHA digest. Then when I did the registration, I compared the timestamp portion to the current timestamp. With simple subtraction, like say less than 86400, means only allowing the code to be good for 24 hours(60*60*24), thus time expiring registration codes.

    No worries about the 9 digit timestamp being in the clear since they can’t tamper with the value in the DB since we clearly match on that and then calculate the time difference between that value and the current time.

    You could accomplish the same by adding another field in the User table or even checking with the creation date, it was just easier to tack it onto the token field since that was its sole purpose.

  2. admin Says:
    May 8th, 2009 at 9:44 am

    thanks for that Tri Bui … I have a timestamp field for a/c creation.. but then i thought why trouble the poor user with a deadline… Maybe I implement it and set the deadline to 2 months or something like dat…

  3. Eddie Says:
    August 5th, 2009 at 8:57 pm

    Glad my document helped you! For those concerned with expiring tokens I recommend a ‘expires’ column for each record. This way your not attached to a fixed date for all tickets. Since I use my tickets for much more than just passwords. Example – make password reset last a day, but maybe image sharing tokens last a week or longer. Purge the table of ‘expired’ tickets every time you validate – keeps your table clean too.

  4. tictipoe Says:
    January 10th, 2010 at 3:27 pm

    Thanx .. nice & simple, good if you dont have to rewrite things yourself all the time.

  5. thomas Says:
    June 23rd, 2010 at 8:59 pm

    thx a lot from germany….this helped me a lot…although i have a tiny problem

    the token gets saved and the complete activation-link sent. but if i click the link i do not get redirected to my verify.ctp, i get to my login page. the view is in the correct file and exists as a function in my controller…also active is not updated to “1” either…any ideas??

    the weird thing: i commented all “redirect” commands out and cake is still redirecting me..why cant he go to activate????

    thx a lot 😉

  6. admin Says:
    July 13th, 2010 at 8:05 pm

    Hello Thomas,

    I am not sure what your problem is, but maybe the redirect page you have set up is viewable only when logged in. After token is verified, you need to login again to view pages.

    Hope that makes sense.

  7. Matt Says:
    December 19th, 2010 at 9:29 pm

    Hey, thanks for the code. Looks all well and good, but I’m having the same issue as Thomas, not getting my ‘activate’ column updating to 1. Its also allowing users to log in even though their activate column is still 0. From the code it looks like it should work though…anyone have suggestions? Much appreciated.

    FYI I’m running CakePHP 1.3 and have ACL handling my permissions.

  8. admin Says:
    December 19th, 2010 at 10:03 pm

    Hello Matt and Thomas,

    just a question, do you see this: $this->Session->setFlash(‘Your registration is complete’);


  9. Matt Says:
    December 20th, 2010 at 8:57 am

    Yes, when I encountered this I was still getting the message that “Your registration is complete”

    My solution was to just call saveField on the row in question like so:

    function verify(){
    if (!empty($this->passedArgs[‘n’]) && !empty($this->passedArgs[‘t’])) {
    $name = $this->passedArgs[‘n’];
    $tokenhash = $this->passedArgs[‘t’];
    // You must get the user’s id to tell saveField what record its working on
    $results = $this->User->find(‘first’, array(‘conditions’ => array(‘username’ => $name)));

    if ($results[‘User’][‘activate’] != 1) {
    if($results[‘User’][‘tokenhash’]==$tokenhash) {
    //use the id to target the user’s record
    $this->User->id = $results[‘User’][‘id’];
    //just update the field in question
    $this->User->saveField(‘activate’, 1);

    $this->Session->setFlash(‘Your registration is complete: ‘);

    } else {
    $this->Session->setFlash(‘The token does not match’);
    } else {
    $this->Session->setFlash(‘Token has alredy been used’);
    } else {
    $this->Session->setFlash(‘There was no token provided for confirmation’);

    Hope this helps!

  10. niharika Says:
    July 18th, 2012 at 2:26 pm

    why [‘n’] and [‘t’] arguments are recognized and verified functions….

  11. roshan Says:
    July 18th, 2012 at 2:30 pm

    why [‘n’] and [‘t’]are not recognized functions,????????

  12. RobertD Says:
    March 23rd, 2013 at 7:44 pm

    Thanks a lot for this tutorial, Works like a charm in cakephp 2.2.

    Best wishes.

  13. admin Says:
    October 7th, 2013 at 8:07 am

    That’s good news. Its been almost 4 years since I wrote it, I am glad it still works.

  14. Nolie Pogi Says:
    October 14th, 2013 at 8:15 pm

    it helps me a lot. I shall try it.

  15. admin Says:
    October 15th, 2013 at 4:57 am

    Let me know how it works out for you. I can make updates to the code based on your feedback.

  16. Taleeb Ahmad Says:
    January 12th, 2014 at 6:07 pm

    Your code generate 2 errors.

    1. Form requires only 1 email address.

    2.An internal error has occurred.

Leave a Reply

© 2009, Nikhil Hullur | Entries RSS Comments RSS