...

View Full Version : Can you change an actual COOKIE in Perl?



pppebble88
11-19-2009, 03:30 AM
I am trying to change the actual value of a cookie based on a set of conditionals. For example, after my user authenticates , I am connecting to a mySQL database to capture the role of the user and then store that value in a variable. However, in order for that "role" to be updated on the other pages, I have to modify the ACTUAL cookie...Below is the code I am trying to use to do this...Any help you could offer would be appreciated...Thanks.

Code that captures the stored cookie and sets the variables appropriately...


@theCookie = cookie('honorCookie');

if(@theCookie) {
$role = substr(@theCookie[0],5);
$userID = substr(@theCookie[1],7);
$loggedIn = 1;

}
else {
print qq{<meta http-equiv="REFRESH" content="0;URL=https://WEB SITE">\n};
}


Code to modify the cookie


...previous code omitted...
# PREPARE THE QUERY
my $query = "SELECT * FROM $tablename WHERE User = '$userID'";
my $query_handle = $connect->prepare($query);

# EXECUTE THE QUERY
$query_handle->execute();

while (@row = $query_handle->fetchrow_array) {
$roleIn = "$row[2]";
$to_set = cookie(-name => "role",
-value => "$roleIn",
);
@theCookie = cookie('honorCookie');
print ("$to_set");
@theCookie[0] = $roleIn;
}

it career
11-19-2009, 05:05 AM
Do not you need to use -cookie to set the cookie ?

pppebble88
11-19-2009, 05:13 AM
I set the cookie in an ASP page...I currently use



$name = cookie("username");


to fetch the cookie...

If i try to use



$theCookie = $cgi->cookie('honorCookie');


to fetch the cookie, I get the following error...



Can't call method "cookie" on an undefined value at D:\InetPub\PERL LOCATION line 16.


I am not sure what to do here...Thanks.

pppebble88
11-19-2009, 06:38 AM
DISREGARD PREVIOUS POST

Here is where I stand...Everything works properly, except that for some reason, at the top of my page, it displays the following:



Set-Cookie: role=Super; path=/ Date: Thu, 19 Nov 2009 06:35:10 GMT Content-Type: text/html; charset=ISO-8859-1

The code that does all of this is below:



use DBI;
use DBD::mysql;
use CGI qw( :standard );
use CGI::Carp qw(fatalsToBrowser);
print (header);

$userCookie = cookie('user');
#print "$userCookie";

if($userCookie) {
$userID = $userCookie;
$loggedIn = 1;
}
else {
print qq{<meta http-equiv="REFRESH" content="0;URL=SERVER">\n};
}

if($loggedIn) {
# CONFIG VARIABLES
$platform = "";
$database = "";
$host = "";
$port = "";
$tablename = "";
$user = "i";
$pw = "";

# DATA SOURCE NAME
$dsn = "dbi:$platform:$database:$host:$port";

# PERL DBI CONNECT
$connect = DBI->connect($dsn, $user, $pw)
or die "Connection Error: $DBI::errstr\n";

# PREPARE THE QUERY
my $query = "SELECT * FROM $tablename WHERE User = '$userID'";
my $query_handle = $connect->prepare($query);

# EXECUTE THE QUERY
$query_handle->execute();

while (@row = $query_handle->fetchrow_array) {
$roleIn = "$row[2]";
$roleCookie = cookie(-name => "role",
-value => "$roleIn",
-path => "/",
);
}

}

# HTTP HEADER
print (header -cookie => $roleCookie);


THE CATCH--> I realize I have "print (header)" in two places. However, if I don't have it at the top, it doesn't receive the value of the "$userCookie" and the rest of the validation doesn't work...I am at a loss as to how I should re-arrange the "print(header) / print(header -cookie => $roleCookie)'" lines...Thanks for the help.

FishMonger
11-19-2009, 03:44 PM
The CGI::header function does not deal with receiving cookie info, it sends the cookie to the client.

Your first print header() function sends the HTTP header without the cookie info. All print statements (to STDOUT) after that header is sent will be seen as the HTML content, which is why you're seeing the cookie data in the browser.

Remove the first print header statement and add these pragmas.



use strict;
use warnings;


The strict pragma will force you to declare your vars as lexical vars instead of globals with the my keyword.

example:

my $userCookie = cookie('user');

Once you fix those issues, we can move on to troubleshoot the cookie retrieval.

FYI, It would be better to use server side sessions instead of the cookies.

pppebble88
11-20-2009, 07:04 PM
We added use strict to the header, and we put the my declaration in fron t of variables as needed by use strict.

The new code still prints the cookie Set header on the page instead of chaning the cookie (same problem)

Could you please advise what we need to change in order to get this cookie set properly.




#!/usr/bin/perl


#source: http://forums.speedguide.net/showthread.php?t=190821
#source: http://articles.techrepublic.com.com/5100-10878_11-1045105.html
#source: http://www.gossland.com/course/cgi_use/cookies.html

use DBI;
use DBD::mysql;
use CGI qw( :standard );
use CGI::Carp qw(fatalsToBrowser);
use CGI;
use strict;
use warnings;

print (header);

my $userCookie =cookie('user');
print "$userCookie";

if($userCookie) {
my $userID = $userCookie;
my $loggedIn = 1;
}
else {
print qq{<meta http-equiv="REFRESH" content="0;URL=https://ADDRESS">\n};
}

if($loggedIn) {
#CONFIG VARIABLES
my $platform = "";
my $database = "i";
my $host = "";
my $tablename = "";
my $user = "";
my $pw = "";

#DATA SOURCE NAME
my $dsn = "dbi:$platform:$database:$host:$port";

#PERL DBI CONNECT
my $connect = DBI->connect($dsn, $user, $pw)
or die "Connection Error: $DBI::errstr\n";

#PREPARE THE QUERY
my $query = "SELECT * FROM $tablename WHERE User = '$userID'";
my $query_handle = $connect->prepare($query);

#EXECUTE THE QUERY
$query_handle->execute();

while (@row = $query_handle->fetchrow_array) {
my $roleIn = "$row[2]";
my $roleCookie = cookie(-name => "role",
-value => "$roleIn",
-path => "/",
);
}

}

# HTTP HEADER
print (header -cookie => $roleCookie);

FishMonger
11-20-2009, 07:26 PM
I added the code tags for you, but in the future please use the code tags when posting your code.

Remove this line:

print (header);


And either remove this print statement or put it after sending the header.

print "$userCookie";

pppebble88
11-20-2009, 07:29 PM
FishMonger,

Thanks for the help. I just got PRK eye surgey, so I am having a rough time looking @ a computer screen. I removed the line you just mentioned...Below is the code as it stands and what the browser is telling us. THANKS FOR ALL OF THE HELP SO FAR!



#!/usr/bin/perl


#source: http://forums.speedguide.net/showthread.php?t=190821
#source: http://articles.techrepublic.com.com/5100-10878_11-1045105.html
#source: http://www.gossland.com/course/cgi_use/cookies.html

use DBI;
use DBD::mysql;
use CGI qw( :standard );
use CGI::Carp qw(fatalsToBrowser);
use CGI;
use strict;
use warnings;

my $userCookie =cookie('user');
print "$userCookie";

if($userCookie) {
my $userID = $userCookie;
my $loggedIn = 1;
}
else {
print qq{<meta http-equiv="REFRESH" content="0;URL=https://address">\n};
}

if($loggedIn) {
#CONFIG VARIABLES
my $platform = "";
my $database = "";
my $host = "";
my $tablename = "";
my $user = "";
my $pw = "";

#DATA SOURCE NAME
my $dsn = "dbi:$platform:$database:$host:$port";

#PERL DBI CONNECT
my $connect = DBI->connect($dsn, $user, $pw)
or die "Connection Error: $DBI::errstr\n";

#PREPARE THE QUERY
my $query = "SELECT * FROM $tablename WHERE User = '$userID'";
my $query_handle = $connect->prepare($query);

#EXECUTE THE QUERY
$query_handle->execute();

while (@row = $query_handle->fetchrow_array) {
my $roleIn = "$row[2]";
my $roleCookie = cookie(-name => "role",
-value => "$roleIn",
-path => "/",
);
}

}

# HTTP HEADER
print (header -cookie => $roleCookie);


Error:


Software error:

Global symbol "$loggedIn" requires explicit package name at D:\InetPub\it350\www.team2.it350.cs.usna.edu\honorBase.pl line 28.
Global symbol "$port" requires explicit package name at D:\InetPub\it350\www.team2.it350.cs.usna.edu\honorBase.pl line 38.
Global symbol "$userID" requires explicit package name at D:\InetPub\it350\www.team2.it350.cs.usna.edu\honorBase.pl line 45.
Global symbol "@row" requires explicit package name at D:\InetPub\it350\www.team2.it350.cs.usna.edu\honorBase.pl line 51.
Global symbol "@row" requires explicit package name at D:\InetPub\it350\www.team2.it350.cs.usna.edu\honorBase.pl line 52.
Global symbol "$roleCookie" requires explicit package name at D:\InetPub\it350\www.team2.it350.cs.usna.edu\honorBase.pl line 62.
Global symbol "$roleCookie" requires explicit package name at D:\InetPub\it350\www.team2.it350.cs.usna.edu\honorBase.pl line 134.
Global symbol "$roleCookie" requires explicit package name at D:\InetPub\it350\www.team2.it350.cs.usna.edu\honorBase.pl line 148.
Global symbol "$roleCookie" requires explicit package name at D:\InetPub\it350\www.team2.it350.cs.usna.edu\honorBase.pl line 149.
Global symbol "$roleCookie" requires explicit package name at D:\InetPub\it350\www.team2.it350.cs.usna.edu\honorBase.pl line 151.
Execution of D:\InetPub\it350\www.team2.it350.cs.usna.edu\honorBase.pl aborted due to compilation errors.

FishMonger
11-20-2009, 07:34 PM
The my keyword creates a lexical var that is limited to the scope in which it was declared. Which means that
my $roleCookie = ...is local to the while loop and therefore won't be accessible outside of that block.

You need to declare $roleCookie in the main body of the script to give it file scope and then assign its value in the while loop.

FishMonger
11-20-2009, 07:43 PM
Try this (it will probably need a little more tweaking).


#!/usr/bin/perl

use DBI;
use DBD::mysql;
use CGI qw( :standard );
use CGI::Carp qw(fatalsToBrowser);
use CGI;
use strict;
use warnings;

my $userCookie = cookie('user');
my $loggedIn = 1 if $userCookie;

if( not $loggedIn ) {
print redirect("https://some_url_address");
exit;
}


#CONFIG VARIABLES
my $platform = "";
my $database = "";
my $host = "";
my $tablename = "";
my $user = "";
my $pw = "";

#DATA SOURCE NAME
my $dsn = "dbi:$platform:$database:$host:$port";

#PERL DBI CONNECT
my $connect = DBI->connect($dsn, $user, $pw)
or die "Connection Error: $DBI::errstr\n";

#PREPARE THE QUERY
my $query = "SELECT * FROM $tablename WHERE User = '$userID'";
my $query_handle = $connect->prepare($query);

#EXECUTE THE QUERY
$query_handle->execute();

while (@row = $query_handle->fetchrow_array) {
my $roleIn = "$row[2]";
my $roleCookie = cookie(-name => "role",
-value => "$roleIn",
-path => "/",
);
}

# HTTP HEADER
print (header -cookie => $roleCookie);

pppebble88
11-21-2009, 04:12 AM
Fish Monger,

Thanks for all of the help thus far. I put the code you posted in our file and for some reason am still getting the "explicit file" errors. Below is the code as it stands and the errors as we are receiving them...Again, thanks for all of the help with this...I feel like it must be really close...BTW, i Like the logic you used with the "if(not logged in)" then do this, instead of the other way around...


Also, after the MAIN code section, we havehave a few PERL code lines that I will post BELOW the main section of code...You will see what i mean below...

Code at the TOP of honorBase.pl



#!/usr/bin/perl


#source: http://forums.speedguide.net/showthread.php?t=190821
#source: http://articles.techrepublic.com.com/5100-10878_11-1045105.html
#source: http://www.gossland.com/course/cgi_use/cookies.html
#source: http://codingforums.com/showthread.php?p=889840#post889840


use DBI;
use DBD::mysql;
use CGI qw( :standard );
use CGI::Carp qw(fatalsToBrowser);
use CGI;
use strict;
use warnings;



my $userCookie = cookie('user');
my $loggedIn = 1 if $userCookie;

if( not $loggedIn ) {
print redirect("https://some_url_address");
exit;
}

#CONFIG VARIABLES
my $platform = "";
my $database = "";
my $host = "";
my $tablename = "";
my $user = "";
my $pw = "";

#DATA SOURCE NAME
my $dsn = "dbi:$platform:$database:$host:$port";

#PERL DBI CONNECT
my $connect = DBI->connect($dsn, $user, $pw)
or die "Connection Error: $DBI::errstr\n";

#PREPARE THE QUERY
my $query = "SELECT * FROM $tablename WHERE User = '$userID'";
my $query_handle = $connect->prepare($query);

#EXECUTE THE QUERY
$query_handle->execute();

while (@row = $query_handle->fetchrow_array) {
my $roleIn = "$row[2]";
my $roleCookie = cookie(-name => "role",
-value => "$roleIn",
-path => "/",
);
}

# HTTP HEADER
print (header -cookie => $roleCookie);


Code lower in the file



if(substr($roleCookie,7) eq "Super") {
print ":: <a href='https://ADDRESS'>Insert XYZ Case</a>";
}

***LOWER IN FILE ***

if($roleCookie eq "Super") {
print "<font color='red'>Logged in as $userCookie $roleCookie</font>";
}
else{print "<font color='red'>Logged in as $userCookie $roleCookie</font>"; }


ERRORS:


Software error:

Global symbol "$port" requires explicit package name at D:\InetPub\it350\/url] line 37.
Global symbol "$userID" requires explicit package name at D:\InetPub\it350\[url] line 44.
Global symbol "@row" requires explicit package name at D:\InetPub\it350\ line 50.
Global symbol "@row" requires explicit package name at D:\InetPub\it350\ line 51.
Global symbol "$roleCookie" requires explicit package name at D:\InetPub\it350\ line 59.
Global symbol "$roleCookie" requires explicit package name at D:\InetPub\it350\ line 131.
Global symbol "$roleCookie" requires explicit package name at D:\InetPub\it350\ line 145.
Global symbol "$roleCookie" requires explicit package name at D:\InetPub\it350\ line 146.
Global symbol "$roleCookie" requires explicit package name at D:\InetPub\it350\ line 148.
Execution of honorBase.pl aborted due to compilation errors.

For help, please send mail to this site's webmaster, giving this error message and the time and date of the error.


THANKS!

FishMonger
11-21-2009, 06:47 PM
Did you read post #9 where I explained why you're getting those errors?

pppebble88
11-22-2009, 03:38 AM
FishMonger,

Making progress...I went back and added initializations for the variables that I was getting errors on. The page displays properly, but it still does not create the "role" cookie on the user's computer...The code is below...I tried to print the "query" and the "roleIn" variables, and neither of them print...Thanks for all of the help.



#!/usr/bin/perl


#source: http://forums.speedguide.net/showthread.php?t=190821
#source: http://articles.techrepublic.com.com/5100-10878_11-1045105.html
#source: http://www.gossland.com/course/cgi_use/cookies.html


use DBI;
use DBD::mysql;
use CGI qw( :standard );
use CGI::Carp qw(fatalsToBrowser);
use CGI;
use strict;
use warnings;


my $userCookie = cookie('user');
my $loggedIn = 1 if $userCookie;
my @row = "";
my $roleCookie = "";

if( not $loggedIn ) {
print redirect("ADDRESS");
exit;
}

#CONFIG VARIABLES
my $platform = "";
my $database = "";
my $port = "";
my $host = "";
my $tablename = "";
my $user = "";
my $pw = "";

#DATA SOURCE NAME
my $dsn = "dbi:$platform:$database:$host:$port";

#PERL DBI CONNECT
my $connect = DBI->connect($dsn, $user, $pw)
or die "Connection Error: $DBI::errstr\n";

#PREPARE THE QUERY
my $query = "SELECT * FROM $tablename WHERE User = '$userCookie'";
my $query_handle = $connect->prepare($query);
print ("$query");

#EXECUTE THE QUERY
$query_handle->execute();

while (@row = $query_handle->fetchrow_array) {
my $roleIn = "$row[2]";
print ("$roleIn");
my $roleCookie = cookie(-name => "role",
-value => "$roleIn",
-path => "/",
);
}

# HTTP HEADER
print (header -cookie => $roleCookie);

FishMonger
11-22-2009, 04:00 AM
Thatr code should have given you an internal server error. If it didn't, then the script you tested is not the same as the one you posted.

The first output sent needs to be the HTTP header, but you have that as the last output.

pppebble88
11-22-2009, 04:07 AM
Fish Monger,

I just tried to move the "print header" to the very top line (after declaring the packages used) and it gives me an error...Is that the line you are talking about? I am not sure why I am not getting an internal server error...The exact code I posted is the one I am using...Why should I get an internal server error? Can you be more explicit on which print line I should change? Thanks.

bazz
11-22-2009, 07:09 AM
Until FishMonger comes back you may try this.
The header code needs to be near the top. I would try it where I have shown it below.




#!/usr/bin/perl


#source: http://forums.speedguide.net/showthread.php?t=190821
#source: http://articles.techrepublic.com.com/5100-10878_11-1045105.html
#source: http://www.gossland.com/course/cgi_use/cookies.html


use DBI;
use DBD::mysql;
use CGI qw( :standard );
use CGI::Carp qw(fatalsToBrowser);
use CGI;
use strict;
use warnings;




my $userCookie = cookie('user');
my $loggedIn = 1 if $userCookie;
my @row = "";
my $roleCookie = "";

if( not $loggedIn ) {
print redirect("ADDRESS");
exit;
}


# HTTP HEADER
print (header -cookie => $roleCookie);

#CONFIG VARIABLES
my $platform = "";
my $database = "";
my $port = "";
my $host = "";
my $tablename = "";
my $user = "";
my $pw = "";

#DATA SOURCE NAME
my $dsn = "dbi:$platform:$database:$host:$port";

#PERL DBI CONNECT
my $connect = DBI->connect($dsn, $user, $pw)
or die "Connection Error: $DBI::errstr\n";

#PREPARE THE QUERY
my $query = "SELECT * FROM $tablename WHERE User = '$userCookie'";
my $query_handle = $connect->prepare($query);
print ("$query");

#EXECUTE THE QUERY
$query_handle->execute();

while (@row = $query_handle->fetchrow_array) {
my $roleIn = "$row[2]";
print ("$roleIn");
my $roleCookie = cookie(-name => "role",
-value => "$roleIn",
-path => "/",
);
}




what is the error you receive currently?

bazz

FishMonger
11-22-2009, 05:22 PM
You should have received an error because you have several print statements before sending the http header. Which browser and web server are you using? Since you didn't receive the error, one or the other is not adhering to the HTTP standards and is sending the header for you.

Since the header that you want to send needs to include the cookie which sets the user's roll, you need to print that header after the db calls.

I have a cleaned up version that should do what you need, however this appears to be your homework assignment so I can't simply give you a complete solution.

pppebble88
11-22-2009, 05:27 PM
Fish Monger,

I am using FIreFox to open...When I open it with GooGLe Chrome, it gives me an error...When I run "perl -w" on the file in my command prompt, it gives me a 302 Error. So, you say I need to print the header after the DB call...is that not what I do right now? My question is, how can I call the http print header if the cookie variable I want to print to the header is not created until the last lines of code? Thanks for the help thus far...

FishMonger
11-22-2009, 05:58 PM
You're confusing the HTTP header with the HTML content.

The cookie data needs to be in the http header, not the html content which is where you were outputting it.

Ok, I guess I'll break down and post an adjusted version.

#!/usr/bin/perl

use DBI;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use CGI;
use strict;
use warnings;

my $cgi = CGI->new;
my $user = $cgi->cookie('user');

# depending on how the cookie was set in ASP
# you may need to parse $user for later use in the db call
if( not $user ) {
print $cgi->redirect('http://url_address');
exit;
}

my $platform = 'mysql';
my $database = '';
my $host = '';
my $table = '';
my $dbuser = '';
my $pw = '';

my $dsn = "dbi:$platform:$database:$host";
my $dbh = DBI->connect($dsn, $dbuser, $pw, {RaiseError => 1})
or die "Connection Error: $DBI::errstr\n";

my $sth = $dbh->prepare("SELECT roll FROM $table WHERE User = ?");
$sth->execute($user);

my ($role) = $sth->fetchrow_array;
$sth->finish;

my $roleCookie = $cgi->cookie(
-name => 'role',
-value => $role,
-path => '/',
);

print $cgi->header(-cookie => $roleCookie);

pppebble88
11-23-2009, 02:37 AM
Fish Monger,

I am getting the following error with your code


Software error:

DBD::mysql::st execute failed: called with 1 bind variables when 0 are needed at D:\InetPub\it350\www.team2.it350.cs.usna.edu\honorBase.pl line 43.


Code I am using is below:



#!/usr/bin/perl



#source: http://forums.speedguide.net/showthread.php?t=190821
#source: http://articles.techrepublic.com.com/5100-10878_11-1045105.html
#source: http://www.gossland.com/course/cgi_use/cookies.html


use DBI;
use DBD::mysql;
use CGI qw( :standard );
use CGI::Carp qw(fatalsToBrowser);
use CGI;
use strict;
use warnings;
my $table="";
my $userCookie="";

my $cgi = CGI->new;
my $user = $cgi->cookie('user');

# depending on how the cookie was set in ASP
# you may need to parse $user for later use in the db call
if( not $user ) {
print $cgi->redirect('http://ADDRESS');
exit;
}

# CONFIG VARIABLES
my $platform = 'l';
my $database = 'i';
my $host = '';
my $table = '';
my $dbuser = '';
my $pw = '';

my $dsn = "dbi:$platform:$database:$host";
my $dbh = DBI->connect($dsn, $dbuser, $pw, {RaiseError => 1})
or die "Connection Error: $DBI::errstr\n";

my $sth = $dbh->prepare("SELECT * FROM $table WHERE User = '$user'");
$sth->execute($sth);

my ($role) = $sth->fetchrow_array;
$sth->finish;

my $roleCookie = $cgi->cookie(
-name => 'role',
-value => $role,
-path => '/',
);

print $cgi->header(-cookie => $roleCookie);

bazz
11-23-2009, 03:47 AM
The error is due to you putting a value into the query when none is needed.



$sth->execute($sth);


if your query were to use a PLACEHOLDER (as FishMonger showed), instead of a directly inputted value (ie your WHERE User = '$user'"), then you wold have the query like this



my $sth = $dbh->prepare("SELECT *
FROM
$table
WHERE User = ?
");
$sth->execute($user);


bazz

pppebble88
11-23-2009, 03:53 AM
here is FINAL code I used...and it works!!!!



#!/usr/bin/perl


#source: http://forums.speedguide.net/showthread.php?t=190821
#source: http://articles.techrepublic.com.com/5100-10878_11-1045105.html
#source: http://www.gossland.com/course/cgi_use/cookies.html


use DBI;
use DBD::mysql;
use CGI qw( :standard );
use CGI::Carp qw(fatalsToBrowser);
use CGI;
use strict;
use warnings;
my $cgi = CGI->new;
my $user = $cgi->cookie('user');

#check if properly authenticated
if( not $user ) {
print $cgi->redirect('http://ADDRESS');
exit;
}

# CONFIG VARIABLES
my $platform = "";
my $database = "";
my $host = "";
my $table = "";
my $dbuser = "";
my $pw = "";

my $dsn = "dbi:$platform:$database:$host";
my $dbh = DBI->connect($dsn, $dbuser, $pw, {RaiseError => 1})
or die "Connection Error: $DBI::errstr\n";

my $sth = $dbh->prepare("SELECT * FROM $table WHERE User = '$user'");
$sth->execute();

my (@role) = $sth->fetchrow_array;
$sth->finish;

my $roleCookie = $cgi->cookie(
-name => 'role',
-value => @role[2],
-path => '/',
);
my $roleValue = substr($roleCookie,5,5);

print $cgi->header(-cookie => $roleCookie);

Do you know the code to DELETE a cookie...that way we can use it for the "logout" button?

THANKS!



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum