Page 1 of 2

Setting a cookie

Posted: Sun Aug 03, 2003 8:59 am
by evilmonkey
Hello.

I use sessions to control whether a user is logged in or not accross my website. I would like to give the user an option to have his details remebered, so he doesn't have to log in each time (much like the PHPBB board). How would I go about doing this? I imagine I would have to set a cookie, but from what I read up o the internet, it only explains how to use a cookie like I currently use a session.

Any help is greatly appreciated.

Cheers!

Posted: Sun Aug 03, 2003 9:22 am
by patrikG
Store the session-details (user, login etc) under the session_id in the db, then set a non-expiring cookie on the visitor's machine containing the session_id.
Every time he comes and visits your site from that machine you match the cookie session_id against the db session_id and, if they do match, pull the details out of the db and log him on automatically.

Posted: Sun Aug 03, 2003 9:44 am
by evilmonkey
Uhh, let me see if i got this rght...

Set a cookie in the remote computer:

Code: Select all

setcookie('donotask', $_SESSION['id'], 'donotask.vagonweb.com', 0);
And then insert it into a MySQL database? If i already have a users table in a MySQL database, can it be possible to integrate the session_id into it, or will it mess up my whole database?

Also, can I then use $_SESSION varibales instead of $_COOKIE variables on the rest of my pages so i don't have to reprogram the whole site?

Cheers!

Posted: Sun Aug 03, 2003 10:10 am
by patrikG
Just add a field "session_id" to your user-table.
And yes, you only need to read out the cookie once (i.e. retrieve the former session_id), then use session_name() to assign the session either the user-name or the session_id.

Example:

patrikG visits your site, registers and ticks the checkbox "Log me on each visit". You set a cookie on patrikG's machine containing the session_id (38f76ec876ae896a876efe8f678623) and write username (patrikG) password (****) and session_id (38f76ec876ae896a876efe8f678623) into your user-table.

Next time patrikG visits you check for the cookie, read out the session_id, check whether there is a user who has that session_id and, if there is a match, read the data from user-table and log him on. Assign the session_id as the session_name.
Tattaaaa: patrikG can work logged in without having logged in manually.

Posted: Sun Aug 03, 2003 10:23 am
by evilmonkey
Uhh, ok...

Just one more question. I understand how to write the data to the cookie. now all I have to do is understand how to read the data from the cookie. Once I have that, all I'd have to do (on my main page) is;

Code: Select all

<?php
if (isset($COOKIE_SET)) {
$sql="SELECT username, userlever FROM users WHERE session_id=//cookie session id, don't know how to read it"
$result=mysql_query($sql, $db);
$row=mysql_fetch_assoc($result);
session_start();
$_SESSION['username']=$row['useranme'];
$_SESSION['userlever']=$row['userlevel'];
$_SESSION['auth']=true;
?>
Is the gist right?

Thanks for your help.

Posted: Sun Aug 03, 2003 11:31 am
by patrikG
Have a look at setcookie().

Code: Select all

if(empty($_COOKIE["myCookieName"]))
    header("location: no_cookie.php")
else
{
$sql="SELECT username, userlever FROM users WHERE session_id='".$_COOKIE['session_id']."'
$result=mysql_query($sql, $db);
$row=mysql_fetch_assoc($result);
session_start();
$_SESSION['username']=$row['useranme'];
$_SESSION['userlever']=$row['userlevel'];
$_SESSION['auth']=true;
}
Note: you can't set and read a cookie on the same page. If a cookie is set, you can access the values by using $_COOKIE["myCookieName"].

Posted: Sun Aug 03, 2003 1:05 pm
by evilmonkey
Hello. I have really appreciate all the help you have given me. I tried playing around with this, this is what i got for my code:

This is the login processing page. On the previous page, there was a textbox for the username, a password box for a password and a check box for remembering the login details. The check box's variable is $remeber, and it can have a value of "" or "yes:. Here's the code:

Code: Select all

<?php
//there are output buffers in this script 
   	$db=mysql_connect("localhost", "", "");
    	mysql_select_db("vagonweb_pcdna", $db);
    	session_start();
    	//call mysql
    	$query="SELECT * FROM users WHERE username='". mysql_escape_string(stripslashes($_POST['username']))."' AND password='". mysql_escape_string(stripslashes(md5($_POST['password'])))."'";
    	$result=mysql_query($query, $db);
    	if (mysql_num_rows($result)==1)
    	{   // if 1 result was returned
    	$row=mysql_fetch_assoc($result);
    	$_SESSION['auth'] = true;
    	$_SESSION['username'] = $_POST['username'];
    	$_SESSION['password'] = $_POST['password'];
    	$_SESSION['group'] = $row['group'];
    	if ($remeber=="yes") //if a user has chosen to be remebered
    	{
    		$sid=session_id();
    		setcookie("dnalogin", $sid, time()+60*60*24*30*12, "/", "donotask.vagonweb.com", 0); //the cookie is set for 1 year
    		$sqll="SELECT sessid FROM users WHERE username='".mysql_escape_string(stripslashes($_POST['username']))."' AND password='". mysql_escape_string(stripslashes(md5($_POST['password'])))."'";
    		$ress=mysql_query($sqll, $db);
    		$rowww=mysql_fetch_assoc($ress);
    		if ($row['sessid']=="")
    		{
    			$sql="INSERT INTO users (sessid) VALUES (".$sid.")";
    			$res=mysql_query($sql, $db);
    		}
    		else
    		{
    			$sql="UPDATE users SET sessid=".$sid;
    			$res=mysql_query($sql, $db);
    		}
    		
    	}
    	echo "<p align="center"><b><u>Please wait while we log you in...</p></b></u>";
?>
   <meta http-equiv="refresh" content="3;url=index.php">
<?php
    	} 
    	else 
    	{
    		$_SESSION['auth'] = false;
    		$_SESSION['username'] = '';
    		echo "<p align="center"><b><u>Sorry, but that user info is incorrect. You have specified an inactive user or a wrong password. Redirecting back to the login page...</p></b></u>"
?>   
   <meta http-equiv="refresh" content="3;url=login.php">
<?php
    	}
    }
?>
Ok, that was the login script. The first problem is that it doesn't set the session_id in the database. Any obvious problems there? I checked if the cookie existed, it did in fact exist, and this is it:

Code: Select all

dnalogin
5b1d66eece25601954decddc51515d4c
donotask.vagonweb.com/
1536
2164567680
29652170
482886704
29579751
*
So the cookie gets written. Now, I created a script that I will use as an include file at the top of selected pages accross my site. This script will check if a user is logged in. if not, It will check if there is a cookie. If there is one, the user will be logged in automatically. Here's the code:

Code: Select all

<?php
session_start();
if ($_SESSION['auth']!==true) //if there is an authorized session, we skip checking the cookie
{
	if (!empty($_COOKIE['dnalogin']))
	{
		$db=mysql_connect("localhost", "vagonweb_dna", "evil");
    	mysql_select_db("vagonweb_pcdna", $db);
		$sql="SELECT * FROM users WHERE sessid=".$_COOKIE['dnalogin'];
		$result=mysql_query($sql, $db);
		$row=mysql_fetch_assoc($result);
		$_SESSION['auth'] = true;
    	$_SESSION['username'] = $row['username'];
    	$_SESSION['password'] = $row['password'];
    	$_SESSION['group'] = $row['group'];
	}
}
?>
This code gives me an error at line 20 (the mysql_fetch_assoc() line). HOWEVER...I stay logged in. I haven't checked all aspects yet, but something is wrong, if there is an error, sessid in the database is empty, and i stay logged in.

I really appreciate you reading this post. And help is greatly appreciated. Thanks.

Posted: Mon Aug 04, 2003 8:38 am
by evilmonkey
Can anyone see any errors in this?

Posted: Mon Aug 04, 2003 10:40 am
by patrikG
Sorry, I gotta be brief. Mondays are full-on.

your first script:

Code: Select all

$rowww=mysql_fetch_assoc($ress);
          if ($row['sessid']=="")
          {
             $sql="INSERT INTO users (sessid) VALUES (".$sid.")";
//you create a new row in the table containing 
//only the session_id with that sql-statement.
             $res=mysql_query($sql, $db);
          }
          else
          {
             $sql="UPDATE users SET sessid=".$sid;
             $res=mysql_query($sql, $db);
          }
Instead try

Code: Select all

$rowww=mysql_fetch_assoc($ress);
          if ($row['sessid']=="")
          {
             $sql="UPDATE users SET sessid=".$sid." WHERE username='". mysql_escape_string(stripslashes($_POST['username']))."'";
             $res=mysql_query($sql, $db) or die ('Username '.$_POST["username"].' does not exist.');
          }

Posted: Mon Aug 04, 2003 4:33 pm
by evilmonkey
ok, I got it to write the $sid into the database (thanks for the code). However, it is still returning an error at cookiecheck.php. Can you please check if I'm calling the cookie right and if I'm storing the information the correct way.

I was also wondering how I could delete a cookie. If a user logs out, I would like to destroy the cookie on his machine.

Sorry you were busy earlier, we have a holiday here today. :D

Thakns for the help.

Posted: Mon Aug 04, 2003 5:52 pm
by patrikG
use setcookie to delete a cookie:
php manual wrote: // set the expiration date to one hour ago
setcookie ("TestCookie", "", time() - 3600);
setcookie ("TestCookie", "", time() - 3600, "/~rasmus/", ".utoronto.ca", 1);
I am not quite sure what's wrong with your script 2, I've added mysql_error after the db-query. Post the error message you get

Code: Select all

session_start();
if (empty($_SESSION['auth']) && !empty($_COOKIE["dnalogin"])) //if there is an authorized session, we skip checking the cookie
	{
     $db=mysql_connect("localhost", "vagonweb_dna", "evil");
     mysql_select_db("vagonweb_pcdna", $db);
     $sql="SELECT * FROM users WHERE sessid=".$_COOKIE["dnalogin"];
     $result=mysql_query($sql, $db) or die ('<h3>Error:</h3>'.mysql_error());
     if ($row=mysql_fetch_assoc($result))
		{
     	foreach($row as $key=>$value)
			$_SESSION[$key] = $value;
		$_SESSION=true;
		}
	else
		echo '<h3>Error mysql_fetch_assoc:</h3>'.mysql_error();
	}

Posted: Mon Aug 04, 2003 6:26 pm
by evilmonkey
Err...

Code: Select all

You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'ab370706192743866b368360' at line 1
this is the PHP Script:

Code: Select all

session_start();
if ($_SESSION['auth']!==true) //if there is an authorized session, we skip checking the cookie
{
	if (!empty($_COOKIE['dnalogin']))
	{
		$db=mysql_connect("localhost", "vagonweb_dna", "evil");
		mysql_select_db("vagonweb_pcdna", $db);
		$sql="SELECT * FROM users WHERE sessid=".$_COOKIE['dnalogin'];
		$result=mysql_query($sql, $db) or die (mysql_error());
		if ($row=mysql_fetch_assoc($result))
		{
			$_SESSION['auth'] = true;
			$_SESSION['username'] = $row['username'];
			$_SESSION['password'] = $row['password'];
			$_SESSION['group'] = $row['group'];
		}
		else
		{
			echo "fetch assoc error is ".mysql_error();
		}
	}
}

Posted: Mon Aug 04, 2003 6:31 pm
by patrikG
Instead of

Code: Select all

$sql="SELECT * FROM users WHERE sessid=".$_COOKIE['dnalogin'];
try

Code: Select all

$sql="SELECT * FROM users WHERE sessid='".$_COOKIE['dnalogin']."'";

Posted: Mon Aug 04, 2003 6:31 pm
by evilmonkey
Just out of curiosity, isn't it easier to store the username in the cookie? Use some encryption algorith (not MD5), because I think this returns because the SID that got stored in the database (for me) is: 3e646894ab370706192743866b368360. And looking at what the error returns, that is not right.

Cheers!

Posted: Tue Aug 05, 2003 2:19 pm
by patrikG
Yes, you can use the username, but the principle is the same. write cookie, logged-in, and read cookie, match user-db, logged in.

Same thing basically.

I prefer using the session_id for three reasons:
1. Cookies are always insecure. I don't want to store any "direct" personal information such as a username in there.
2. md5() can return the same hash for two different strings (thus rendering it useless). The shorter the string md5() is seeded with, the greater the likelihood it returns the same hash for two different strings. Usernames are shorter than session_ids.
Of course, the chances of md5 misbehaving are not very great (2^128+1), but I'd rather err on the more secure side.
3. Session_ids can be very useful for encryption.