Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Delete or change cookies?

Status
Not open for further replies.

Kirsle

Programmer
Jan 21, 2006
1,179
US
I'm developing a new site engine and I'm having a little trouble with the cookies.

How this site engine works is, the pages are in txt files. All the "plain" text is kept in $rb->{content}, and all the "perl" text is evaluated at the end if there was any, which oftentimes manipulates $rb->{content} further.

An <include> tag can allow one page to include the contents of another.

So, here are some pages of interest:

login.txt (the login page)
Code:
<title>Sign In</title>

<div class="infobox">
	<div class="infotitle">Sign In to Your Account</div>
	<div class="infotext">
		%error%
		<form name="login" action="%link=>dologin" method="post">
		<input type="hidden" name="linkto" value="user">

		<div align="center">
		<table border="0" cellspacing="2" cellpadding="0">
			<tr>
				<td align="left" valign="middle">
					Username:
				</td>
				<td align="left" valign="middle">
					<input type="text" size="20" name="user" class="entry">
				</td>
			</tr>
			<tr>
				<td align="left" valign="middle">
					Password:
				</td>
				<td align="left" valign="middle">
					<input type="password" size="20" name="pass" class="entry">
				</td>
			</tr>
			<tr>
				<td colspan="2" align="right" valign="middle">
					<input type="checkbox" name="remember" value="yes" id="memory">
						<label for="memory">Remember me</label>
				</td>
			</tr>
			<tr>
				<td colspan="2" align="right" valign="middle">
					<input type="submit" value="Sign In!" class="bttn">
					<input type="button" value="New User" class="bttn" onClick='self.location="%link=>newuser"'>
				</td>
			</tr>
		</table>
		</div>

		</form>
	</div>
</div><p>

<perl>
	my $error = $query{error} || '';

	if ($error eq 'username') {
		$rb->{content} =~ s/%error%/Error: that username doesn't exist!/g;
	}
	elsif ($error eq 'password') {
		$rb->{content} =~ s/%error%/Error: your password was incorrect!/g;
	}
	else {
		$rb->{content} =~ s/%error%//g;
	}

	# If we're already logged in...
	if ($rb->{logged_in} == 1) {
		$rb->{content} = "";
	}
</perl>

dologin.txt (the "do login" page, which sets cookies and whatnot)
Code:
<title>Sign In</title>

<perl>
	# Get login arguments.
	my $linkto = $query{linkto} || 'user';
	my $user   = $query{user};
	my $pass   = $query{pass};
	my $memory = $query{remember} || 'no';

	# Format the username.
	$user = &normalize ($user);

	# Encode their password.
	$pass = md5_hex ($pass);

	# See if this user exists.
	if (&userExists($user)) {
		# Load their profile.
		&profileLoad ($user);

		# Get the user's actual password and key.
		my $md5 = $rb->{users}->{$user}->{password};
		my $key = $rb->{users}->{$user}->{crypt};

		# See if the passwords match.
		if ($pass eq $md5) {
			# Login was successful. Generate their Session ID.
			my $ses = &genSession ($user,$md5,$key);

			# Create their cookies.
			my $usercookie;
			if ($memory eq 'yes') {
				$usercookie = $cgi->cookie (
					-name    => $rb->{site}->{cookies}->{username},
					-expires => '30d',
					-value   => $user,
					-domain  => $rb->{site}->{cookies}->{domain},
				);
			}
			else {
				$usercookie = $cgi->cookie (
					-name    => $rb->{site}->{cookies}->{username},
					-value   => $user,
					-domain  => $rb->{site}->{cookies}->{domain},
				);
			}
			my $sescookie = $cgi->cookie (
				-name   => $rb->{site}->{cookies}->{session},
				-value  => $ses,
				-domain => $rb->{site}->{cookies}->{domain},
			);

			# Print the headers.
			print $cgi->header (
				-content_type => 'text/html',
				-cookie       => [ $usercookie, $sescookie ],
			);
			$rb->{header} = 1;

			$rb->{content} = "<include:$linkto>";
		}
		else {
			$rb->{content} = "<include:login?error=password>";
		}
	}
	else {
		$rb->{content} = "<include:login?error=username>";
	}
</perl>

And this is the page I'm having trouble with: I'm trying to delete the session cookie, but it doesn't delete it, it leaves it completely alone (I've tried croak $cgi->header to see which headers it was printing and they appear to be fine).

Code:
<title>Sign Out</title>

<div align="center">
	<div class="infobox">
		<div class="infotext" align="center">
			<a href="%link=>index">Return to RainbowBoi</a>
		</div>
	</div>
</div>

<perl>
	# Clear the session cookie.
	my $sescookie = $cgi->cookie (
		-name    => $rb->{site}->{cookies}->{session},
		-value   => '',
		-expires => '-1d',
	);

	print $cgi->header (
		-content_type => 'text/html',
		-cookie => [ $sescookie ]
	);
	$rb->{header} = 1;
</perl>

$rb->{header} is a flag which, when set, tells the main script not to print out the HTTP headers because one of the pages already printed their own.

If you need any more information, tell me and I'll try to give as much info as possible if it will help the issue at all.

Session cookies are session temporary so it's not an urgent issue, just I'd like to allow people to log out without closing all their browser windows.

Thanks in advance.
 
IIRC CGI::Session has that functionality already, might be worth looking at how they handle it. just glanced at the docs, and the 'flush' method is what you should be looking out for

HTH

Paul
------------------------------------
Spend an hour a week on CPAN, helps cure all known programming ailments ;-)
 
Hey:

I did some Google searches on Perl CGI cookies and they told me to delete them the same way that I had been doing it.

As a test, I called my dologin.cgi with different login credentials while I was still logged in, and my cookies changed to show the new login info. So I compared the cookie setters in the two scripts, and found the problem:

The code setting the cookie had a -domain on it, the cookie deleting it didn't. I guess the browser might've thought of these as two different cookies, and that the -domain one was more specific and it overrides the one without the -domain, hence the cookie wasn't changed or deleted.

Code:
<title>Sign Out</title>

<div align="center">
	<div class="infobox">
		<div class="infotext" align="center">
			<a href="%link=>index">Return to RainbowBoi</a>
		</div>
	</div>
</div>

<perl>
	# Clear the session cookie.
	my $sescookie = $cgi->cookie (
		-name    => $xy->{site}->{cookies}->{session},
		-value   => 'del',
		-expires => 'Tue, 1 Jan 1980 08:00:00 UTC',
		-domain  => $xy->{site}->{cookies}->{domain},
	);

	print $cgi->header (
		-content_type => 'text/html',
		-cookie => [ $sescookie ]
	);
	$xy->{header} = 1;
</perl>

(and I changed the $rb to $xy engine wide, which is why the variables here aren't consistent with the ones in my first post)
 
glad you got it sorted ;-)

Paul
------------------------------------
Spend an hour a week on CPAN, helps cure all known programming ailments ;-)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top