Code snippets for symfony 1.x

Navigation

Refine Tags

Snippets tagged "usability"

easy cookie validation for user login systems

If you're building a site with a user login system (like Askeet) and your PHP is configured to store session variables in a client-side cookie, the following snippet will improve the usability for users who have disabled cookies.

The following example assumes you already have at least a simple user login system on your site. If not, check out the Askeet tutorial for a great example to get you started.

All users who have disabled cookies will be unable to log into any site that relies on client-side cookies to store session variables. If you don't validate cookies and provide notification, these users will never know why they couldn't log in to your site.

Try the following if you'd like to see this firsthand.

Unfortunately, Askeet also provides the perfect example here as well. (Sorry guys!)

Not much happened, right? You're not logged in and you don't know why. (Well, you do now.)

What we're going to do is augment an existing login system to provide users with notification that your site requires cookies.

To do this, we're going to attempt to set a cookie on the login page and verify that it was created once the login form is submitted. Since a cookie is stored only after the page is loaded, it takes two pages to validate the user's setting. Fortunately, the login process takes two pages!

Edit your existing login action code by adding the following two setCookie() functions.

The first setCookie() sets the validation cookie when the login action is first loaded. (If you use your login on several pages as a component/partial, move this first setCookie() to the login form component.)

The second setCookie() deletes the validation cookie upon successful login. If this cookie is not deleted, the validation could return a false positive if the user disables cookies at a later date. (When cookies are disabled, new cookies can't be written, but old cookies can be read.)

module_dir/actions/actions.class.php:

public function executeLogin()
{
  if ($this->getRequest()->getMethod() != sfRequest::POST)
  {      
    sfContext::getInstance()->getResponse()->setCookie('cookies_enabled', 'true', time()+60*60*24, '/');    
  }
  else
  {
    sfContext::getInstance()->getResponse()->setCookie('cookies_enabled', '', 0, '/');    
    $this->redirect('@homepage');
  }
}

Enable cookie validation by adding the following code to your existing login validation. The validator takes two parameters, cookie_name and cookie_error. The cookie_name parameter is, oddly enough, the name of the cookie we'll use to validate and it should match the cookie set in the above code.

The other parameter, cookie_error, is the error message that will be returned if the user has cookies disabled. Typically, validation errors are phrases like "Invalid username" or "Password must contain 6-8 characters". But we're going to use "cookies_disabled" and I'll show you why in a few minutes.

IMPORTANT: The cookie validation should occur first.

module_dir/validate/login.yml:

methods:
  post: [username]
 
names:
  username:
    required:     true
    required_msg: 
    validators:   [cookiesEnabledValidator, userValidator]
 
cookiesEnabledValidator:
  class:          myCookiesEnabledValidator
  param:
    cookie_name:  cookies_enabled
    cookie_error: cookies_disabled
 
userValidator:
  class:          myLoginValidator
  param:
    password:     password
    username_error: Invalid username.
    password_error: Invalid password.

Copy the following code to one of your lib directories. Since it only deals with the login action, I choose to keep it in my user module's lib directory.

module_dir/lib/myCookiesEnabledValidator.class.php:

class myCookiesEnabledValidator extends sfValidator
{    
  public function initialize($context, $parameters = null)
  {
    // initialize parent
    parent::initialize($context);
 
    // set defaults
    $this->setParameter('cookie_name', sfContext::getInstance()->getStorage()->getParameter('session_name'));
    $this->setParameter('cookie_error', 'This site requires cookies.');
    $this->getParameterHolder()->add($parameters);
 
    return true;
  }
 
  public function execute(&$value, &$error)
  {    
    if (sfContext::getInstance()->getRequest()->getCookie($this->getParameter('cookie_name')) === null)
    {
      $error = $this->getParameter('cookie_error');
      return false;
    }
    return true;
  }
}

Now, since it takes two pages to set and read a cookie it wouldn't make sense to return the user to the form right away. If they enable their cookies they'll still have to submit the form twice before they'll login successfully. I prefer to send them to a page which notifies them that the site requires cookies and explains how they can enable them. (Plus, this gives us the extra click we need to set that validation cookie!)

So we'll check for the cookie validation error before returning to the form so we can redirect the user to our help page if necessary. The error we check for in the username parameter must match the cookie_error we defined in the login.yml.

module_dir/actions/actions.class.php:

public function handleErrorLogin()
{
  if (sfContext::getInstance()->getRequest()->getError('username') == 'cookies_disabled')
  {
    $this->redirect('@about_cookies');
  }
  return sfView::SUCCESS;
}

So that's it. Throw in an about cookies page and you're all set.

If I made any mistakes, I apologize. It's 5am on a school night.

by dave furf on 2007-05-11, tagged cookie  login  session  storage  usability  validation 
(1 comment)

easy cookie validation for user login systems

If you're building a site with a user login system (like Askeet) and your PHP is configured to store session variables in a client-side cookie, the following snippet will improve the usability for users who have disabled cookies.

The following example assumes you already have at least a simple user login system on your site. If not, check out the Askeet tutorial for a great example to get you started.

All users who have disabled cookies will be unable to log into any site that relies on client-side cookies to store session variables. If you don't validate cookies and provide notification, these users will never know why they couldn't log in to your site.

Try the following if you'd like to see this firsthand.

Unfortunately, Askeet also provides the perfect example here as well. (Sorry guys!)

Not much happened, right? You're not logged in and you don't know why. (Well, you do now.)

What we're going to do is augment an existing login system to provide users with notification that your site requires cookies.

To do this, we're going to attempt to set a cookie on the login page and verify that it was created once the login form is submitted. Since a cookie is stored only after the page is loaded, it takes two pages to validate the user's setting. Fortunately, the login process takes two pages!

Edit your existing login action code by adding the following two setCookie() functions.

The first setCookie() sets the validation cookie when the login action is first loaded. (If you use your login on several pages as a component/partial, move this first setCookie() to the login form component.)

The second setCookie() deletes the validation cookie upon successful login. If this cookie is not deleted, the validation could return a false positive if the user disables cookies at a later date. (When cookies are disabled, new cookies can't be written, but old cookies can be read.)

module_dir/actions/actions.class.php:

public function executeLogin()
{
  if ($this->getRequest()->getMethod() != sfRequest::POST)
  {      
    sfContext::getInstance()->getResponse()->setCookie('cookies_enabled', 'true', time()+60*60*24, '/');    
  }
  else
  {
    sfContext::getInstance()->getResponse()->setCookie('cookies_enabled', '', 0, '/');    
    $this->redirect('@homepage');
  }
}

Enable cookie validation by adding the following code to your existing login validation. The validator takes two parameters, cookie_name and cookie_error. The cookie_name parameter is, oddly enough, the name of the cookie we'll use to validate and it should match the cookie set in the above code.

The other parameter, cookie_error, is the error message that will be returned if the user has cookies disabled. Typically, validation errors are phrases like "Invalid username" or "Password must contain 6-8 characters". But we're going to use "cookies_disabled" and I'll show you why in a few minutes.

IMPORTANT: The cookie validation should occur first.

module_dir/validate/login.yml:

methods:
  post: [username]
 
names:
  username:
    required:     true
    required_msg: 
    validators:   [cookiesEnabledValidator, userValidator]
 
cookiesEnabledValidator:
  class:          myCookiesEnabledValidator
  param:
    cookie_name:  cookies_enabled
    cookie_error: cookies_disabled
 
userValidator:
  class:          myLoginValidator
  param:
    password:     password
    username_error: Invalid username.
    password_error: Invalid password.

Copy the following code to one of your lib directories. Since it only deals with the login action, I choose to keep it in my user module's lib directory.

module_dir/lib/myCookiesEnabledValidator.class.php:

class myCookiesEnabledValidator extends sfValidator
{    
  public function initialize($context, $parameters = null)
  {
    // initialize parent
    parent::initialize($context);
 
    // set defaults
    $this->setParameter('cookie_name', sfContext::getInstance()->getStorage()->getParameter('session_name'));
    $this->setParameter('cookie_error', 'This site requires cookies.');
    $this->getParameterHolder()->add($parameters);
 
    return true;
  }
 
  public function execute(&$value, &$error)
  {    
    if (sfContext::getInstance()->getRequest()->getCookie($this->getParameter('cookie_name')) === null)
    {
      $error = $this->getParameter('cookie_error');
      return false;
    }
    return true;
  }
}

Now, since it takes two pages to set and read a cookie it wouldn't make sense to return the user to the form right away. If they enable their cookies they'll still have to submit the form twice before they'll login successfully. I prefer to send them to a page which notifies them that the site requires cookies and explains how they can enable them. (Plus, this gives us the extra click we need to set that validation cookie!)

So we'll check for the cookie validation error before returning to the form so we can redirect the user to our help page if necessary. The error we check for in the username parameter must match the cookie_error we defined in the login.yml.

module_dir/actions/actions.class.php:

public function handleErrorLogin()
{
  if (sfContext::getInstance()->getRequest()->getError('username') == 'cookies_disabled')
  {
    $this->redirect('@about_cookies');
  }
  return sfView::SUCCESS;
}

So that's it. Throw in an about cookies page and you're all set.

If I made any mistakes, I apologize. It's 5am on a school night.

by whoknows on 2007-05-11, tagged cookie  login  session  storage  usability  validation