Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

CGI Session Not Working

by ninjazin (Initiate)
on Mar 22, 2015 at 15:34 UTC ( [id://1120895]=perlquestion: print w/replies, xml ) Need Help??

ninjazin has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks, I'm new to perl and to this community as well. I'm creating a login system with perl but getting problem abour session, i'm unable to get session data to another page. here my code, login.pl
#!/usr/bin/perl print "Content-type: text/html\n\n"; require 'learn/db_connect.pl'; use CGI; use CGI::Session qw(); use DBI; use warnings; use Digest::SHA qw(hmac_sha512_hex); $q = new CGI; my $cgi = new CGI; if($q->request_method eq "POST"){ my $uname = $q->param('uname'); my $pass = $q->param('pass'); if(defined($uname) && $uname ne ""){ if(defined($pass) && $pass ne ""){ my $pass_hash = hmac_sha512_hex($pass); my $dbh = connectDB(); my $sth = $dbh->prepare("SELECT count(id) as counted FROM +perl_users WHERE `username` = ? AND `password` = ?"); $sth->execute($uname, $pass_hash); my $ref = $sth->fetchrow_hashref(); if($ref->{'counted'} == 1){ my $sql001 = $dbh->prepare("SELECT * FROM perl_users W +HERE `username` = ? AND `password` = ?"); $sql001->execute($uname, $pass_hash); my $result = $sql001->fetchrow_hashref(); $user_id = $result->{'id'}; $username = $result->{'username'}; my $s = CGI::Session->new; $s->param("user_id" => $user_id); my $id = $s->id; print "<script>window.location.href = 'profile.pl?toke +n=".$id."';</script>"; }else{ print "<script>window.location.href = 'index.pl?error= +Invalid Username OR Password.';</script>"; } }else{ print "<script>window.location.href = 'index.pl?error=plea +se fill all fields';</script>"; } }else{ print "<script>window.location.href = 'index.pl?error=please f +ill all fields';</script>"; } }else{ print "<script>window.location.href = 'index.pl';</script>"; }
profile.pl (where i need session data)
#!/usr/bin/perl print "Content-type: text/html\n\n"; use CGI; use CGI::Session qw(); use DBI; use warnings; $get = new CGI; $token = $get->param('token'); my $s = CGI::Session->new($token); print $s->param("user_id");
Whats wrong i'm doing here ? I have tried lots of things with CGI:Session and still no luck, i'm stuck with this since last two days and feeling dumb now as i'm not new to programming. Any gelp will be highly appreciated. Thanks.

Replies are listed 'Best First'.
Re: CGI Session Not Working
by golux (Chaplain) on Mar 22, 2015 at 17:24 UTC

    Hi ninjazin,

    First, you should really use not only 'warnings', but 'strict' as well:

    use strict; use warnings;

    Secondly, you have to show us the code for "learn/db_connect.pl". (And is "index.pl" the thing which calls "login.pl"? It wouldn't hurt to show us that as well).

    Third, assuming you have access to a webserver where you can test this, try putting the following line with the other 'use' statements:

    use CGI::Carp qw{ fatalsToBrowser };

    while debugging. This will make the browser display any fatal errors, rather than having to rely on your webserver logfiles. Additionally (andx only while debugging), you can make warnings become fatal errors (which with "fatalsToBrowser" will make them conviently appear in the output, with:

    use warnings FATAL => "all";

    and cleanup any warnings that appear, such as the one I'm getting:

    Use of unitialized value in numeric eq (==) at login.cgi line 50.
    which is this line:
    if($ref->{'counted'} == 1){

    where $ref wasn't assigned correctly because in the code:

    my $dbh = connectDB(); my $sth = $dbh->prepare("SELECT count(id) as counted FROM perl_use +rs WHERE `username` = ? AND `password` = ?"); $sth->execute($uname, $pass_hash); my $ref = $sth->fetchrow_hashref();

    $dbh never got assigned (It's part of the missing code that you haven't shown us in "learn/db_connect").

    Another aid you can employ in debugging is to create a subroutine in login.pl called debug():

    sub debug { my ($msg) = @_; my $lnum = (caller)[2]; print qq{<pre><b>Debug [line $lnum]</b>: &nbsp; $msg</pre>}; }

    now any time you want to debug any line of your code, you can call debug() with an informational message. For example, to make sure that the request method was really a "POST", do this:

    if($q->request_method eq "POST"){ debug("Yes, the request method WAS 'POST'");

    and to ascertain that you're getting the right values for $uname and $pass, you could do:

    my $uname = $q->param('uname'); my $pass = $q->param('pass'); debug("Passed values were: Uname=$uname Pass=$pass");

    Finally, you can really simplify your logic by refactoring your if ... else clauses to handle the reverse cases first, and get them out of the way. Also, though it's not strictly necessary, I find it easier to break long lines up into shorter ones, especially when you have long SQL text.

    Here's how I would rewrite everything:

    #!/usr/bin/perl print "Content-type: text/html\n\n"; require 'learn/db_connect.pl'; use CGI; use CGI::Session qw(); use CGI::Carp qw{ fatalsToBrowser }; use DBI; use strict; # use warnings; # Put this back in when done with FATAL => +"all" use warnings FATAL => "all"; my $username; my $user_id; use File::Basename; my $prog = 'profile.cgi'; use Digest::SHA qw(hmac_sha512_hex); my $q = new CGI; my $cgi = new CGI; my $meth = $q->request_method; sub debug { my ($msg) = @_; my $lnum = (caller)[2]; print qq{<pre><b>Debug [line $lnum]</b>: &nbsp; $msg</pre>}; } # If it's NOT POST, go back to index.pl if($q->request_method ne "POST"){ print "<script>window.location.href = 'index.pl';</script>"; exit; } # Get parameters my $uname = $q->param('uname'); my $pass = $q->param('pass'); debug("Passed values were: Uname=$uname Pass=$pass"); # A better way to write if (!defined($uname) or $uname eq "") { .. +. } # is if (!($uname || "")) { ... } ## if (!($uname || "")) { my $err = qq{error=please fill all fields}; print "<script>window.location.href = 'index.pl?$error';</scri +pt>"; exit; } my $pass_hash = hmac_sha512_hex($pass); my $dbh = connectDB(); my $sql = qq{ SELECT count(id) as counted FROM perl_users WHERE `username` = ? AND `password` = ? }; $sth->execute($uname, $pass_hash); my $ref = $sth->fetchrow_hashref(); if ($ref->{'counted'} != 1) { my $err = qq{error=Invalid Username Or Password.}; print "<script>window.location.href = 'index.pl?$error';</scri +pt>"; exit; } # Successful up to this point -- note the lack of hard-to-read, # multiply nested if ... else .. else ... else clauses. ## $sql = qq{ SELECT * FROM perl_users WHERE `username` = ? AND `password` = + ? }; my $sql001 = $dbh->prepare($sql); $sql001->execute($uname, $pass_hash); my $result = $sql001->fetchrow_hashref(); $user_id = $result->{'id'}; $username = $result->{'username'}; my $s = CGI::Session->new; $s->param("user_id" => $user_id); my $id = $s->id; print "<script>window.location.href = 'profile.pl?token=$id';</scr +ipt>";
    say  substr+lc crypt(qw $i3 SI$),4,5
Re: CGI Session Not Working
by Your Mother (Archbishop) on Mar 22, 2015 at 16:54 UTC

    Any gelp? Are you sure? You haven’t seen the quantity and nature of the gelp around here. Also you need a license to take gelp otherwise it’s catch and release. :P

    You’re printing headers without session cookies so there is no way to read the session information back from the client. I recommend following the example code a bit more closely (for example, letting CGI::Session print your header, you should never be doing headers manually, i.e., print "Content-Type…): CGI::Session. If that’s enough to help you go back to the documents and solve your problem, great. If not, someone will help you with a bit more sample code here soon and if not, I will later when I have time for more than comedy.

      I searched for "gelp" on the Urban Dictionary. NSFW. Do you mean гэлп?
      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

        :P I was quoting the OP’s typo: Any gelp will be highly appreciated. My Cyrillic is worse than even my Chinese.

      Thanks for help, just had to read things again, and it is not how i wanted, and i had to rewrite some things. Thank you so much all for helping me , this is just my second perl program i'm writing :) Have a good day!
Re: CGI Session Not Working
by chacham (Prior) on Mar 23, 2015 at 15:20 UTC

    my $sql001 = $dbh->prepare("SELECT * FROM perl_users WHERE `username` = ? AND `password` = ?");

    Side comment: It is best to not use SELECT * outside of EXISTS() clauses and ad-hoc queries. Changing it to, "SELECT id, username" can avoid issues due to column reordering and added or removed columns, save on network traffic, and is self-documenting.

Re: CGI Session Not Working
by anonymized user 468275 (Curate) on Mar 25, 2015 at 18:22 UTC
    Apart from already observed by others:-
    new CGI seems to be called several times. I see no reason why it can't be just once for this code. In most cases one initialises an object by assigning it to a "new" for a class and can in most cases expect to stick to that one object for all further uses of the class.
    Your use of CGI::Session seems limited to the new method but no other methods are called and the object will be destroyed as soon as it goes out of scope - try to decide what scope the session object needs and declare the object there. Also take a look through the methods here to decide which ones you need to call. CGI::Session

    One world, one people

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1120895]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2024-04-19 21:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found