• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 216
  • Last Modified:

Remember Me cookie questions

I have a simple login page that queries a database and then redirects to the index page with a successful authentication.  I would like to add a checkbox on the initial screen to set a cookie for the person's username so it will automatically be filled in when they come back the next time.  I have a few questions about setting this up.

I don't think that the cookie is being set because I am using a <cflocation> tag to redirect with.  Is that correct?  How should I set the cookie?  

If another person wants to login and inputs a different name and then checks the remember me box will the cookie get overwritten or will there be two cookies?

Do you have any examples of doing this?  Thanks a ton!
  • 2
1 Solution
You're right about the <cflocation> tag:

"Because a page must finish processing before a cookie is set in the browser, you will find that if you set a cookie and then use the <cflocation> tag to go to a different page, the cookie will never be set."  - Ben Forta et al.

You could state the values set in the session scope and then have the cookies be set on the index page pointed to by the <cflocation> tag. This seems like a really backwards way of doing things but it is a possibility. Sorry, I don't have any example code.


When another user logs in on the same computer, yes, it will overwrite the cookies if they check the box.

Instead of using cflocation to set the cookie, I use cfheader, javascript or meta tags:

<!--- cfheader version --->
<cfheader name="location" value="#CGI.Request_URI#">
<cfheader statusCode="302" statusText="Document Moved">

<!--- Javascript version --->
<script language="JavaScript">setTimeout('document.location.href = "<cfoutput>#CGI.Request_URI#</cfoutput>"',1000);</script>

<!--- Meta version --->
<meta http-equiv="refresh" content="1; URL<cfoutput>#CGI.Referer#</cfoutput>">
<refresh url="<cfoutput>#CGI.Referer#</cfoutput>" content="1">
<!--- Then show a brief login page that says they've been successfully logged in --->

For "remembering me" I suggest using session variables with cookies holding the data between visits or session timeout:

<cfif NOT IsDefined("Session.Login") AND NOT IsDefined("Cookie.Login")>
Redirect or Show login screen
<cfelseif NOT IsDefined("Session.Login") AND IsDefined("Cookie.Login")>
Deserialize the cookie with cfwddx, re-query the database into the Session.Login

When I say deserialize, I like to do my last username/password verification query into the Session.Login variable (name attribute of query). As soon as the query is complete, I serialize the Session.Login query into String format (with cfwddx) and use cfcookie to set the cookie with the variable just set. Then I use cfheader to redirect and the user never sees a thing. I think this process is the fastest and least amount of code.

-- Ian
Ike23Author Commented:
Where would I set the cookie value then?  Why would I need to deserialize it?  I think I follow what you are saying except for the "verification query into the Session.Login variable" part.  If I do use Javascript I would need to check that the user has scripting on in the browser.  Actually I use Javascript a lot in my application so I will need to check for that before allowing the user to login.  Is that possible?  Do I need to use the <noscript> tags or should I check on the action page and then redirect back to the login if scripting is disabled?  Thanks for you help.  I am using a CF Component to do the login stuff so I'm not sure if that makes a difference.

Here is a brief run down of how I do my cookie logins: (since you have concerns about compatibility of javascript, I would say to use cfheader)

1. User logs into web site with username and password

2. Username is verified with database to see if it matches with records in the database
      a) If it doesn't match, redirect with message that no username exists

3. Password is verified in a QueryOfQuery (the first query with username is queried again) to see if it matches with the username that was pulled. The name of this query is Session.Login (which places the Login query into a session variable)
      a) If it doesn't, redirect with message that password does not match with username

4. Using cfwddx, the Session.Login query is serialized into a String format of xml (because structures, queries and arrays cannot be placed into a cookie.

5. User is redirected using cfheaders and cfabort (so the cookie is set) to a referer or wherever.

6. The user can now navigate throughout the web site with the session variable.

7. On each page (or in Application.cfm) that is secured, code is put in to check if the session variable exists, if the cookie exists, and what to do in case of different scenarios (one or the other exist - see my previous post).

8. If the session does not exist and the cookie does, it means the user logged in before but the session expired. In this case:

9. The cookie is deserialized with cfwddx from xml to a cf query and put into a temporary query variable.

10. The username and password variables from the query (that was deserialized from the cookie) are then revalidated (steps 1-5) and on we go.

The reason for the revalidation in my code is in case the user's account information is changed. If they are suspended or gain higher access levels, the Session.Login query and subsequent xml cookie will be updated with that information. If your user access levels don't change, then don't worry about revalidation and deserialize with cfwddx directly back into Session.Login (output="Session.Login").

cfcomponent works just fine. I don't use cfcomponents; I use custom tags. What you can do is place the form variables (and when a cookie exists) the deserialized cookie variables and place them like so:

<cf_login username="#Form.Username# *or* #TmpCookieQuery.Username#" password="#Form.Password# *or* #TmpCookieQuery.Password#" redirect="#CGI.HTTP_Referer#">
then run through steps 1-5 in the custom tag.

I hope this helps. Let me know if you have more questions.

-- Ian
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now