Gossamer Forum
Home : Products : Gossamer Links : Version 1.x :

Re: Using cookies to integrate W3T

Quote Reply
Re: Using cookies to integrate W3T In reply to
I'll try to get all the bits and pieces I made changes to.

First off in DB_Utils, you need to add 3 new subs and include them in your @EXPORT = qw/ ... /; line.
Code:
###########################################################################
# set_cookie - Sets a cookie.
# Usage : set_cookie('Name',"Value",?) ? = 0 or 1. 0 = temp, 1 = permanent
###########################################################################
sub set_cookie {

my @cookie = @_;
my ($cookie, $value, $type, $char);
my @Cenc = ('\;','\&','\+','\%','\,','\=','\:\:','\s');
my %Cenc = ('\;','%3B','\&','%26','\+','%2B','\%','%25','\,','%2C','\=','%3D','\:\:','%3A%3A','\s','+');

my $header = '';

for (my $i = 0; $i <= $#cookie; $i = $i + 3) {
($cookie, $value, $type) = @cookie[$i .. $i+2];
foreach $char (@Cenc) {
$cookie =~ s/$char/$Cenc{$char}/g;
$value =~ s/$char/$Cenc{$char}/g;
}
$header = 'Set-Cookie: ' . $cookie . '=' . $value . ';';
if ($type == 1) {
$header .= ' expires=' . 'Thu, 31-Dec-2020 23:00:00 GMT' . ';';
}
$header .= ' path=' . '/' . ';';
print "$header\n";
}
}


###########################################################################
# Get_cookie - Gets all the cookies and returns them in a hash
# Usage: my %cookie = &get_cookie;
###########################################################################
sub get_cookie {

my @cstuff = @_;
my ($cookie, $value, $char, %cookie);

my @Cdec = ('\+', '\%3A\%3A', '\%3D', '\%2C', '\%25', '\%2B', '\%26','\%3B');
my %Cdec = ('\+',' ','\%3A\%3A','::','\%3D','=','\%2C',',','\%25','%','\%2B','+','\%26','&','\%3B',';');

if ($ENV{'HTTP_COOKIE'}) {

foreach (split(/; /,$ENV{'HTTP_COOKIE'})) {

($cookie,$value) = split(/=/);

foreach $char (@Cdec) {

$cookie =~ s/$char/$Cdec{$char}/g;
$value =~ s/$char/$Cdec{$char}/g;

}

$cookie{$cookie} = $value;

}

}

return %cookie;

}

sub cookie_auth {
# ---------------------------------------------------------
# Checks the username/password to make sure it is valid, and
# returns a hash of the user info. If no parameters are provided,
# it gets the username/password from cookies. Returns undef if unable
# to validate or no username/password found.
#
my ($Username, $Password, $Language) = @_;
$Language = shift;

# print "Content-type: text/plain\n\n";
return undef unless $Username and $Password;
my $dbh = new Links: BSQL $LINKS{admin_root_path} . "/defs/Users.def";

my $query = qq!
SELECT Users.*
FROM Users
WHERE Users.Username = '$Username' AND Users.Password = '$Password'
!;
my $sth = $dbh->prepare ($query) or die "Can't prepare: $query. Reason: $!";
$sth->execute() or die "Can't execute: $query. Reason: $!";
my $user = undef;
if ($sth->rows) {
$user = $sth->fetchrow_hashref;
}
return $user;

}

I borrowed these three routines from W3T and ported them into Links, though you will need to add the "path=" in set cookie to make cookies accessible site wide. And use my version of &cookie_auth (w3t::authenticate) because we need to get it's output into a hash format.

Now in HTML_Templates change the load_user sub, to load based on cookies values rather sessions.

Code:
sub load_user {
# --------------------------------------------------------
# Add user information to hash ref by looking up session id.
#
# Commente out the original more effective way,
# that Links loads a users profile, and then
# authenticates the user...

my ($dynamic, $hash, $category_id) = @_;
return $hash unless (defined $dynamic and (ref $dynamic eq 'CGI'));

# if (($dynamic->param('s')) &#0124; &#0124; ($dynamic->cookie('s')) {
# my $s = $dynamic->param('s') &#0124; &#0124; $dynamic->cookie('s') &#0124; &#0124; return $hash;
# $USERS{$s} &#0124; &#0124;= &authenticate ($s);
# my $user = $USERS{$s};
#
# if (ref $user eq 'HASH') {
# if ($user->{Status} eq 'Editor') {
# $user->{isEditor} = $category_id ? &can_edit ($user->{User}, $category_id) : undef;
# }
# foreach (keys %$user) { $hash->{$_} = $user->{$_} unless (exists $hash->{$_}); }
# }
# return $hash;
#
# } else {

my %cookie = &get_cookie();
my $Username = $cookie{'Username'};
my $Password = $cookie{'Password'};
my $Language = $cookie{'language'};
$USERS{$Language} &#0124; &#0124;= &cookie_auth ($Username, $Password, $Language);
my $user = $USERS{$Language};
if (ref $user eq 'HASH') {
if ($user->{Status} eq 'Editor') {
$user->{isEditor} = $category_id ? &can_edit ($user->{User}, $category_id) : undef;
}
foreach (keys %$user) { $hash->{$_} = $user->{$_} unless (exists $hash->{$_}); }
}
return $hash;
# }

}
Note I left the meat of the old sessions code intact for reuse. I tried to get it so depending on wether or not $s is defined it will kick off a session based authentication but, I just keep getting errors. I also worked around defining $s in $USERS{$s} by using my $Language value as a header, this isn't a clean piece of code by any means, but it works...considering I'm not even sure what it is doing...I mean the differences betweens Array's and Hashes became real apparent while working on this!

Right now in user.cgi we need to set a cookie at login so we can make our users info available to the W3T script, as well as to our Links templates, seeing as we no longer use the sessions. So in the sub login_user just before:

Code:
# Create and insert a Session, but first remove sessions older then 1 day.
$db->do (qq!

Add in:
Code:
# Let's initialize some variables to be passed in to our cookie
my $User = $user_r->{'Username'};
my $Pass = $user_r->{'Password'};
my $Lang = $user_r->{'Language'};
# NOW LETS GET COMPATIBLE WITH W3T and set a usable cookie so if
# they wanna go see what's up at the fair grounds they'll already have
# paid to get in!

&set_cookie( 'Username', "$User", 1, 'Password', "$Pass", 1, 'language', "$Lang",1);

If you want other Users variables to be passed in to the cookie, just add them in using the same format. Well that's the bulk of it...I did notice that a few lines down, from where I added in the call to set the cookie at login, there is another cookie being set for the value of $s, at first I tried to use that to print my Username/Password & Language preference into a cookie, but I couldn't get it to print my values along with it, I'm sure it can be done but I just don't know how? SO I added in an extra sub. I'd call this a temporary patch until I fgiure out how to print it in the same $dynamic->cookie. The rest of the mod is basically getting your W3T to work off the same database as Links (tedious chore of renaming all your SQL queries, in all files) then you need to fill out your User Table with whatever info you want to collect from your visitors, making changes to any file that allows them to modify these fields. Then in your templates you need to have pretty much two separate files...one if your visitor is registered and one for non registered. Add to that the side board items that are SSI driven and in each template you actually contain 3 different files. One if it's a static page, one for dynamic users and one for unregistered dynamic users. And if you really want to get nifty...one for visiting Robots, give them their own special page so they can do a better job of placing your site on the search engines!

For an example of what one of my template pages look like send me an email at writecon@mvsource.com , there's probably alot I left out on account of the fact that I've made so many tiny changes to both programs to get them working as one but these are the major ones, to interconnect their usage of registered users without them having to login twice.
Subject Author Views Date
Thread Using cookies to integrate W3T phoule 7156 Mar 7, 2000, 4:16 AM
Post Re: Using cookies to integrate W3T
pugdog 7020 Mar 7, 2000, 6:18 PM
Post Re: Using cookies to integrate W3T
phoule 7070 Mar 7, 2000, 9:47 PM
Post Re: Using cookies to integrate W3T
pugdog 6994 Mar 7, 2000, 9:48 PM
Post Re: Using cookies to integrate W3T
phoule 7086 Mar 8, 2000, 8:18 AM
Post Re: Using cookies to integrate W3T
phoule 7041 Mar 8, 2000, 3:37 PM
Post Re: Using cookies to integrate W3T
pugdog 7003 Mar 8, 2000, 8:05 PM
Post Re: Using cookies to integrate W3T
phoule 6998 Mar 9, 2000, 3:45 AM
Post Re: Using cookies to integrate W3T
patagon 7001 Mar 11, 2000, 3:48 PM
Post Re: Using cookies to integrate W3T
phoule 6982 Mar 11, 2000, 6:52 PM
Post Re: Using cookies to integrate W3T
phoule 6932 Mar 12, 2000, 4:26 AM
Post Re: Using cookies to integrate W3T
patagon 6931 Mar 12, 2000, 8:50 AM
Post Re: Using cookies to integrate W3T
pugdog 6947 Mar 12, 2000, 9:15 AM
Post Re: Using cookies to integrate W3T
phoule 6937 Mar 13, 2000, 3:49 AM
Post Re: Using cookies to integrate W3T
patagon 6931 Mar 13, 2000, 4:20 PM
Post Re: Using cookies to integrate W3T
phoule 6920 Mar 13, 2000, 6:02 PM
Post Re: Using cookies to integrate W3T
pugdog 6936 Mar 13, 2000, 6:04 PM
Post Re: Using cookies to integrate W3T
phoule 6983 Mar 13, 2000, 6:09 PM
Post Re: Using cookies to integrate W3T
phoule 6951 Mar 13, 2000, 8:03 PM
Post Re: Using cookies to integrate W3T
pugdog 6930 Mar 14, 2000, 12:40 AM
Post Re: Using cookies to integrate W3T
phoule 6948 Mar 14, 2000, 3:46 AM
Post Re: Using cookies to integrate W3T
pugdog 6951 Mar 14, 2000, 8:27 AM
Post Re: Using cookies to integrate W3T
patagon 6977 Apr 19, 2000, 2:46 PM