Remember Me cookie questions

Posted on 2004-10-13
Last Modified: 2013-12-24
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!
Question by:Ike23
  • 2

Expert Comment

ID: 12301395
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.



Expert Comment

ID: 12301892
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

Author Comment

ID: 12302268
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.


Accepted Solution

black0ps earned 200 total points
ID: 12304251
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

Featured Post

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In our day to day coding, how many times have we come across a necessity to check whether a URL is a broken link or not? For those of you that answered countless and are using ColdFusion like myself, then this article is for you.  It will show yo…
Meet the world's only “Transparent Cloud™” from Superb Internet Corporation. Now, you can experience firsthand a cloud platform that consistently outperforms Amazon Web Services (AWS), IBM’s Softlayer, and Microsoft’s Azure when it comes to CPU and …
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question