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

In reply to Re: CGI Session Not Working by golux
in thread CGI Session Not Working by ninjazin

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.