Solved

Yet another cookie / remember me question ...

Posted on 2006-10-23
22
285 Views
Last Modified: 2013-12-24
I've read through a lot of previous posts but I'm still a bit confused and need some help.
I have a login page ... login.cfm.
The user enters username and password then clicks the "sign in" button, which takes them back in to the login.cfm page where authentication is done, and if login is successful, they are taken to the
login_successful.cfm page via a <cflocation> tag.
On that page, there are several links. The user clicks one to indicate where they want to go next.
The choices correspond to these pages:
index.cfm
members.cfm
recipeshome.cfm
search.cfm
pantry.cfm

So there are no cflocation tags on the login_successful.cfm.
So ... can I set the cookie on the login_successful.cfm page?
And what is the correct way to do it?
High points because I really need to get this working asap. Thanks.
0
Comment
Question by:alicia1234
  • 13
  • 5
  • 3
  • +1
22 Comments
 
LVL 15

Expert Comment

by:tim_cs
ID: 17794385
Instead of doing it that way why not set the cookies on the login.cfm page and use a different method of forwarding the page?  Otherwise you will have to pass the values you want to save into the cookies to the login_successful.cfm page.  

Some other page forwarding options are given in the answer here http://www.experts-exchange.com/Web/WebDevSoftware/ColdFusion/Q_10946501.html

0
 

Author Comment

by:alicia1234
ID: 17795134
When I read a cookie ... is information passed between the user's pc and the server? This may be a really stupid question but I am new to this. I'm trying to figure out how, once I've set the cookie, I read it and use it to authenticate the user "behind the scenes" without them having to login. Do I need to do all that on my secure server or not?
0
 

Author Comment

by:alicia1234
ID: 17795376
I put this code into my login.cfm page and removed the cflocation redirect:

      <cfcookie name="CWA.user" value="#MM_rsUser.memberID#" expires="never">
      <script>
      location.href='#MM_redirectLoginSuccess#';
      </script>

The cookie does not get set.
0
 

Author Comment

by:alicia1234
ID: 17795550
Here is the entire code of my login.cfm page ... the first time I log in, I get an unsuccessful login (even though the session variable CWA.member_ID gets set, meaning it did go thru the code for successful login). I login again and login is successful, but cookie is still not set. It's probably something to do with the <script></script> but I copied that from another post here so I don't really know how it is supposed to work.

This code is all at the top of my page, before this stuff starts:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

===========================================================

<cfif IsDefined("FORM.username")>
 
  <cfset md5pw = hash("#FORM.password#")>
  <cfquery  name="MM_rsUser" datasource="connCWAmembers">
    SELECT memberID,username,pwdhash,userGroup,firstName
      FROM tblmembers
      WHERE username='#FORM.username#' AND pwdhash='#md5pw#';
  </cfquery>
 
  <cfset MM_redirectLoginSuccess=
  "#ssl#apps/userauth/login_success_cookie.cfm?memID=#MM_rsUser.memberID#">
  <cfset MM_redirectLoginFailed="#ssl#apps/userauth/login_failed.cfm">
 
  <cfif MM_rsUser.RecordCount NEQ 0>
   <!--- login succeeded --->
    <cftry>
      <cflock scope="Session" timeout="30" type="Exclusive">
        <cfset Session.MM_Username=FORM.username>
        <cfset Session.MM_UserAuthorization=MM_rsUser.userGroup[1]>
        <cfset Session.CWA_UserFirstName=MM_rsUser.firstName>
        <cfset Session.CWA_MemberID=MM_rsUser.memberID>
        <cfset sessionID = Session.CFID>
      </cflock>
        
       <!--- record the login in the database --->
        <cfquery datasource="connCWAmembers">
              INSERT INTO tbllogins (memberID, sessionID, logintime)
            VALUES
            (#MM_rsUser.memberID#, #sessionID#, #Now()#
            )
        </cfquery>
        
    <!--- login successful --->
      <!--- <cflocation url="#MM_redirectLoginSuccess#" addtoken="no"> --->
            
      <!--- new cookie stuff --->
                <cfcookie name="CWA.user" value="#MM_rsUser.memberID#" expires="never">
                <script>
      location.href='#MM_redirectLoginSuccess#';
      </script>

    <cfcatch type="Lock">
        <!--- code for handling timeout of cflock --->
    </cfcatch>
    </cftry>
  </cfif>
   <!--- login failed --->
   <cflocation url="#MM_redirectLoginFailed#" addtoken="no">
 
<cfelse>
<!--- Not logging in yet ... blank form --->
  <cfset MM_LoginAction=CGI.SCRIPT_NAME>
  <cfif CGI.QUERY_STRING NEQ "">
    <cfset MM_LoginAction=MM_LoginAction & "?" & XMLFormat(CGI.QUERY_STRING)>
  </cfif>
 
</cfif>
0
 

Author Comment

by:alicia1234
ID: 17795738
I changed tack and put the cookie code into login_success.cfm.
Now the cookie gets created.
However, it shows up as cookie:shea@208.xxx.xxx.xxx  ... that is , it shows my IP address rather thah my domain ..
Also, I delete the cookie (by finding it in files in IE), but when I run my page that test to see if a cookie exists, it still thinks there is one. Do I need to delete it in more than one place?
0
 

Author Comment

by:alicia1234
ID: 17795906
Nevermind the last post ... I was confused about testing on my local pc vs running on my host.

I put the cookie code into the login_success page and tested it on my server and all seems to be working ok ... the cookie does get set. I still do not understand why it wouldn't set when I tried it in login page.

I would still like to understand, however, about reading the cookie ... how to use it. I know how to actually get the value.
But given that I'm using the cookie for "remember me" ... what I do is store the user's memberID in it. Is it enough, then, for me to just check that the cookie exists and grab the memberID and continue on my way ... that is to say, no other "authentication" is required?

Thanks.
0
 
LVL 2

Expert Comment

by:Marco_van_den_Oever
ID: 17837462
The only thing that have to happen is checking if the value of the cookie is the same as the argument you give in the code.

so very simple example:

<cfif Cookie.username eq "henry" and Cookie.password eq "henrypass">
You are validated!
<cfelse>
You are not validated!
</cfif>

And ofcourse the values in this example (eq "henry" - eq "henrypass") can also be checked and compared (with the value of the cookie)  against values in a database.

Is that what you need to know?
0
 

Author Comment

by:alicia1234
ID: 17837655
The value of the cookie is the unique memberID ... so I am assuming that if the cookie exists, then I just grab the memberID and go with it. I don't do any further validation. Is that ok?
0
 
LVL 2

Accepted Solution

by:
Marco_van_den_Oever earned 300 total points
ID: 17838022
I should create a loginpage where you insert a username / password , so that 2 cookies will be created:

cookie.username
cookie.password

If you use only one cookie to validate then it's not really secure, and if you use the unique memberid (that is ofcourse a good choise because it's unique) it's not very secure cause everybody knows that it would be something from number 1 till whatever. Ofcourse others don't know this fact that we know but maybe a hacker will find out.

So i think that tim_cs suggestion is indeed the easiest solution for your problem, i also protect my site with cookies like the above way, it's easy and save.

Did i understand your question ? (sometimes i think left while another is on the right:)
0
 

Author Comment

by:alicia1234
ID: 17838040
Well, I thought that the cookie could only be read by my site ... so I thought the cookie was secure?
The whole point is to NOT have to have them sign in again.
I do have all their info in a database keyed on the member id.
So I'm not quite sure what you are suggesting.
If they login, and check the "remember me" box, the cookie is written. From then on, whenever they access the site, I check for the cookie. If it's there, I grab the MemberID from it, and use that to get data out of the database.
How could a hacker hack into that?
0
 

Author Comment

by:alicia1234
ID: 17838076
Are you saying that, instead, I should store the username and password in the cookie ... and then validate that against the database?
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 2

Expert Comment

by:Marco_van_den_Oever
ID: 17838297
If you now use a login script without cookies, then when the login is succesfull create the cookie.memberid so that's a refer to get more info from a user that should be enough, so you did a great job:)

You could also store the username and password in cookies and then validate against values in the database, then the authentication depends totally on cookies and you have one system of authentication to work with.
0
 
LVL 25

Expert Comment

by:dgrafx
ID: 17846549
I see that this question is still open and you have some good answers, but thought I'd post cause you're not quite there.
First - you cannot set a cookie on the action page if action page is same page as form page - that is why you couldn't set that cookie.
so here is an example login.cfm:
<Form ACTION="auth.cfm" METHOD="POST">
<input TYPE="hidden" NAME="showalert" value="true">
Username<br>            
<input TYPE="TEXT" NAME="username" VALUE="<cfif isdefined("cookie.username")>#cookie.username#</cfif>"><br><br>
Password<br>
<input TYPE="password" NAME="password"><br><br>
<input type="submit" value="Submit">
Remember Me
<INPUT TYPE="CHECKBOX" NAME="SaveInfo" <CFIF IsDefined("Cookie.SaveInfo")> checked</cfif>><br><br>
</form>      

Here is auth.cfm:
<cfquery dataSource="#Request.Datasource#" name="Auth">
SELECT your stuff
FROM Users
where Username = '#trim(form.Username)#'
and Password =
<cfqueryparam value="#form.password#" cfsqltype="CF_SQL_VARCHAR">
</cfquery>

if only one record is matched and case sensitive password match:
<cfif Auth.recordcount eq 1 AND compare(Auth.password,form.password) is 0>      <!--- valid --->
<CFIF StructKeyExists(Form,"SaveInfo")>      
      <CFCOOKIE NAME="SaveInfo" VALUE="TRUE" EXPIRES="never">
      <CFCOOKIE NAME="Username" VALUE="#trim(form.username)#" EXPIRES="never">
      <CFCOOKIE NAME="Password" VALUE="#encrypt(form.password,EncWord)#" EXPIRES="never">
      <!--- EncWord is a var that holds the encryption key lets just define it as "abc123" --->
<CFELSE>                  
      <CFCOOKIE NAME="Username" VALUE="#trim(session.username)#">
      <cfif isDefined("cookie.SaveInfo")>
            <CFCOOKIE NAME="SaveInfo" expires="now">
      </cfif>
      <cfif isDefined("cookie.Password")>
            <CFCOOKIE NAME="Password" expires="now">
      </cfif>
</CFIF>
      <SCRIPT LANGUAGE="JavaScript">            
            location.replace('some page you want to send them to')            
      </SCRIPT>
      <NOScript>
      <META HTTP-EQUIV="Refresh" CONTENT="0;URL=some page you want to send them to">
      </NOScript>
<cfelse><!--- not valid --->
      <cfset structclear(session)>
      <cfif isDefined("cookie.username")>
            <CFCOOKIE NAME="Username" EXPIRES="now">
      </cfif>
      <cfif isDefined("cookie.SaveInfo")>
            <CFCOOKIE NAME="SaveInfo" EXPIRES="now">
      </cfif>
      <cfif isDefined("cookie.Password")>
            <CFCOOKIE NAME="Password" EXPIRES="now">
      </cfif>      
      <SCRIPT LANGUAGE="JavaScript">      
      <CFIF StructKeyExists(Form,"Showalert")>      
            alert("Login Invalid")      
      </cfif>
            location.replace('some page you want to send them to')            
      </SCRIPT>
      <NOScript>
      Login Invalid
      <META HTTP-EQUIV="Refresh" CONTENT="<CFIF StructKeyExists(Form,"Showalert")>4<cfelse>0</cfif>;URL=some page you want to send them to">
      </NOScript>      
</cfif><!--- /valid --->

now to auto login users just do this on your application.cfm file:
First you need a default param - let's call it session.KeepAlive with default of false
<cfset EncWord="abc123">
<cfif Not StructKeyExists(Session,"KeepAlive")>      
      <cflock scope="SESSION" type="EXCLUSIVE" timeout="15">      
            <cfset session.Keepalive=False>
      </cflock>
</cfif>
<cfif Not session.KeepAlive and StructKeyExists(Cookie,"Password") and StructKeyExists(Cookie,"Username")>
      <cflock scope="SESSION" type="EXCLUSIVE" timeout="15">      
            <cfset session.Keepalive=True>
      </cflock>
      <cfset form.username=cookie.username>
      <cfset form.password=decrypt(cookie.password,EncWord)>
      <cfinclude template="auth.cfm">
</cfif>

The reason I'm encrypting your cookie.password is cause cookies can be stolen.
Anyway ...
just try this - it's exactly what you're looking for - if you have any questions just ask.

good luck ...
0
 

Author Comment

by:alicia1234
ID: 17846643
dgrafx: I understand what you are saying, but ...
is there anything wrong with what I have done?
That is ... I have the user log in and I authenticate them against the database. If they have checked the "remember me" box, I set a cookie that contains only their member id.
Thereafter, whenever they access a page (i.e, in Application.cfm) I check for the existence of the cookie. If the cookie exists, I assume they are ok, and I use the memberID in the cookie to customize certain pages and give access to their profile.
If this is not "secure" I would like to know why.
Thanks!

0
 
LVL 25

Assisted Solution

by:dgrafx
dgrafx earned 200 total points
ID: 17846856
I started off just going to point out that you need to encrypt your password cookie, but it turned into more.
If you want to be secure - you need to do this.
A person can and people do steal cookies.
Usually not for the reason to gain access to a site such as yours though.

also - you are using a member id for the cookie.
lets say I knew my member id was 2534 - I might be curious and alter my cookie to see what member id 2535 had going on.
I personally feel that one should just let the user choose username and password - then if "remember Me" set them as cookies as in the example I provided.
Their login is then as secure as they keep their username & password.
0
 

Author Comment

by:alicia1234
ID: 17846869
ok, I understand now ... thanks!
0
 

Author Comment

by:alicia1234
ID: 17847164
so the deal is ... that someone could change their own cookie to try to hack into someone else's info, right?
Could someone "fake" a cookie?
I ask because in order to get a cookie, you'd have to subscribe to my site ... it's a membership thing where you  have to pay a monthly fee. So maybe that would reduce the potential hacker-pool and risk?
0
 
LVL 25

Expert Comment

by:dgrafx
ID: 17847462
sure cookies can be faked
that's why one should really only use a cookie for user convenience like username so on their visit the username field can be pre-populated with cookie.username (for ex)
But if cookie.username is correct along with a correct encrypted password - you have a good chance that this is the correct user.
It all depends on what kind of site you have.
I would never do this if it was a banking site for ex because you are going to attract people who know what they are doing as far as faking or cracking cookies.
a cooking site won't attract crackers - just a vandal or two maybe.
And by the way - I would also change the name of cookie.password to something else - it would make me more comfortable anyway.

0
 
LVL 2

Expert Comment

by:Marco_van_den_Oever
ID: 17848192
nice one dgrafx:)
0
 

Author Comment

by:alicia1234
ID: 17849252
ok .. now I see what you mean about changing the memberid in the cookie (I actually did it).
So ... tell me if this will be ok:
Set cookie1 = username
Set cookie2 = hashed password
When user accesses page, validage username and hashed pwd in cookies with that in db. If match, everything is ok?
0
 

Author Comment

by:alicia1234
ID: 17849414
By jove I think I've got it!!  ;-)
Thanks so much to everyone.
0
 
LVL 2

Expert Comment

by:Marco_van_den_Oever
ID: 17851103
great that it works now! :)
0

Featured Post

Backup Your Microsoft Windows Server®

Backup all your Microsoft Windows Server – on-premises, in remote locations, in private and hybrid clouds. Your entire Windows Server will be backed up in one easy step with patented, block-level disk imaging. We achieve RTOs (recovery time objectives) as low as 15 seconds.

Join & Write a Comment

Suggested Solutions

A web service (http://en.wikipedia.org/wiki/Web_service) is a software related technology that facilitates machine-to-machine interaction over a network. This article helps beginners in creating and consuming a web service using the ColdFusion Ma…
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 …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

762 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now