Xerratus
Happily stressed out, since 1974


 
Wednesday, October 04, 2006
<< Posting via Live Writer
BakersMark.com makes headlines... In a good way >>

The other day I tried to add a simple "Remember me" checkbox to the login.aspx page for a site I'm working on.  Simple enough in theory that I didn't think much of it and gave myself an hour to add it in. 

Here's what I needed it to do:

  • Pre-populate the txtUserName textbox of the last user IF they checked the "Remember me" checkbox.
  • Remember the state of the "Remember me" checkbox so that the user doesn't have to check it each time they log in (or uncheck it).

Sounds simple enough right?  Just add a cookie and check it when login.aspx loads, right?  Wrong.

The problem became clear very early on; the cookies were being cleared when the user logged out.  Since my goal was to access the cookie BEFORE the user logged in, I could not rely on the cookie.  But I HAD to use a cookie, there was no way around it. 

So, after some searching and trial-and-errors, I came up with a simple solution: use JavaScript cookies.  Now it sounds like a bit of a hack but it's not really.  JavaScript has been able to read and write to cookies from the get go. 

So first we need to write some simple script that will read/write to cookies:

function CreateCookie(name, value, days)
{
    
if(days)
    {
        
var date = new Date();
        date.setTime(date.getTime() + (days*
24*60*60*1000));
        
var expires = "; expires=" + date.toGMTString();
    }
    
else var expires = "";
    
    document.cookie = name +
"=" + value + expires + "; path=/";
    
}

function ReadCookie(name)
{
    
var nameEQ = name + "=";
    
var ca = document.cookie.split(';');
    
for(var i = 0; i < ca.length; i++)
    {
        
var c = ca[i];
        
while (c.charAt(0)==' ') c = c.substring(1, c.length);
        
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
    }
    
    
return null;
}

function EraseCookie(name)
{
    CreateCookie(name,
"", -1);
}

Next, we create 2 new custom methods; one to read the cookie when the page loads and the other to write/remove the cookie when the checkbox is checked:

function CheckRememberMe()
{
    
if(ReadCookie("rememberMe") != null)
    {
        document.getElementById(
"txtUserName").value = ReadCookie("rememberMe");
        document.getElementById(
"RememberMe").checked = true;
        document.getElementById(
"txtPassword").focus();
    }
}

function ToggleRememberMe(checked)
{
    
if(checked)
    {
        CreateCookie(
"rememberMe", document.getElementById("txtUserName").value, 30);
    }
    
else
    {
        EraseCookie(
"rememberMe");
    }
}

Now, all that is left is to add an onload event to the body tag and an onclick event to the checkbox:

<body onload="CheckRememberMe();">

(note; since the checkbox value is not used anywhere but the client, I chose not to use a .NET server control)

<input type="checkbox" name="RememberMe" id="RememberMe" onclick="ToggleRememberMe(this.checked);" /><label for="RememberMe">Remember me on this computer</label>

Viola, you're done.  Simple, effective and it can be used by multiple browsers.

Monday, October 09, 2006 11:27:42 AM (Pacific Standard Time, UTC-08:00)
Just to clear up and misunderstandings; this is not .NET code but it IS designed soley to get around .NET's use of authentication cookies.
Monday, October 30, 2006 6:16:01 AM (Pacific Standard Time, UTC-08:00)
John,

I'm not sure I get this part:

"The problem became clear very early on; the cookies were being cleared when the user logged out."

When the user is logging off, the auth ticket is removed, but you stil have the other cookie name value pairs. If you store the last logged in user's userName, id, or whatever you use to identify him, that will not be removed from the cookie collection when the user hits log off. You can also treat the existence of such a value in the collection as the "Remember Me" flag (if you have a userName in there, that means RememberMe's ON, and OFF otherwise).

One more thing. As I think a Login page should not be cached, I think you should go server-side and make it work even without JS enabled.
Monday, October 30, 2006 10:20:54 AM (Pacific Standard Time, UTC-08:00)
Adi,

I tried to use the cookie collection, believe me, but when the user logged off the cookie collection was gone. It sounds easy enough, but try and create a simple "Remember Me" solution and you'll see my dilema.

I didn't want to use the new 2.0 login control because it didn't behave the way I wanted it to.

Perhaps I'll put together a quick demo project showing the problem so that everyone can see how the cookies are removed in action.

Tuesday, October 31, 2006 3:58:00 AM (Pacific Standard Time, UTC-08:00)
Yes, please put a demo somewhere and let's try to see where the problem is.

I'm not a fan of the MS web controls either ;)
Tuesday, October 31, 2006 9:37:45 AM (Pacific Standard Time, UTC-08:00)
Name
E-mail
Home page

Comment (Some html is allowed: a@href@title, b, blockquote@cite, em, i, strike, strong, sub, super, u) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Enter the code shown (prevents robots):

Live Comment Preview