0
votes

I am trying to implement a basic user authorisation system using perl and CGI. The browser (firefox & safari) does not react to the CGI redirect (upon successful login to a new page) or even to a simple print HTML after including jQuery 1.11.13.min.js in the header of the HTML login page. The browser's content area and url textbox remain the same as CGI script were never executed. But I know the scripts were executed.

Here is a summary of the system:
The user is first presented with an HTML login page (login_page.html) which contains a basic login form with 'username' and 'password' fields, the form action is a cgi script (verify.cgi) called using POST.

This script checks if credentials are OK and either redirects to a new CGI script (welcome.cgi) which prints a basic welcome message in HTML or just prints a basic html message of failure there and then (all three files are included further down this post).

However, there is a problem after redirecting to the welcome (CGI) page. The welcome.cgi script is called successfully because I made it print a message in a file in the server. BUT the url-address box of the browser (firefox 41.0.2 and safari 6.2.4) is not updating, the http://..../verify.cgi url remains there. Also, the browser displays the login page html and does not update its content area to the welcome or failed login message html output-ed by the verify.cgi/welcome.cgi scripts.

The problem appears after including the standard jQuery js file (http://code.jquery.com/jquery-1.11.3.min.js) in the header of my login page (in html).

Can anyone help me finding out what I am doing wrong and how to fix it?

Please do not ask why I want to include jQuery. And I prefer to stick with perl than anything else.

General comments about the code and design welcomed.

Many thanks

Here are the three files in their most basic form:

  1. login_page.html
<!doctype html>
<html>
<head>
<!-- this one creates a problem with CGI redirect -->
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>

<!-- this one does not seem to create any problem -->
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>

</head>
<body>
<form action="/bin/verify.cgi" method="post" name="login_form">
 <input type="text" name="username" id="username"><br/>
 <input type="password" name="password" id="password"><br/>
 <input type="submit" value=" Log In " name="login_button"/>
</form>
</body>
</html>
  1. verify.cgi
#!/usr/bin/env perl

use strict;
use warnings;
use CGI::Carp;
use CGI::Session;
use CGI;

my $cgi = CGI->new;

my $username = $cgi->param("username");
my $password = $cgi->param("password");

if( defined($username) &&
    defined($password) &&
    ($username eq 'test') &&
    ($password eq 'test')
){
    # successful login
    my $session = CGI::Session->new(
        "driver:File",
        undef,
        {Directory=>'/tmp'}
    );
    my $sid = $session->id();
    $session->param('username', $username);
    # setup the cookie to the session
    my $cookie = $cgi->cookie(
        -name  => 'CGISESSID',
        -value => $sid
    );
    $session->save_param();
    $session->flush();
    # move on to the next page and place the cookie in the headers
    # the script in the -location is EXECUTED OK - so redirect works
    # however browser does not update URL textbox nor its content page:
    print $cgi->redirect(
            -cookie   => $cookie,
            -url => 'http://c3.myartsonline.com/bin/welcome.cgi'
    );
    # even with this it does not work
    # print $cgi->header() . "<html><body>welcome, login successful</body></html>";

} else {
    # login failed
    # this I can not see in the browser either
    print $cgi->header() . '<html><body>login failed</body></html>';
}
1;
__END__
  1. welcome.cgi
#!/usr/bin/env perl

use strict;
use warnings;
use CGI;
use CGI::Session;
my $cgi = CGI->new;

my ($session, $username) = (undef) x 2;

my $sid = $cgi->cookie('CGISESSID') || $cgi->param('CGISESSID') || undef;
if( defined($sid) ){
    $session = CGI::Session->new(undef, $sid, {Directory=>'/tmp'});
    if( defined($session) ){
        $username = $session->param('username')
    }
}
if( defined($username) ){
    print $cgi->header() . "<html><body>welcome user '$username', login successful</body></html>";
    open(OUT, ">hello");
    print OUT "weclome\n";
    close(OUT);
} else {
    print $cgi->header() . "<html><body>please login first</body></html>";
}
1;
__END__
1
Use the redirect method as described in the CGI.pm documentation under Generating a redirection header. You can see how the headers differ from your current method by running on the command line: compare perl -MCGI -e'print CGI->new->header(-location => "foo")' to perl -MCGI -e'print CGI->new->redirect("foo")' - ThisSuitIsBlackNot
Also, if you're writing new code, I would recommend using something other than CGI.pm. Its use is officially discouraged: "...CGI.pm is no longer considered good practice for developing web applications, including quick prototyping and small web scripts. There are far better, cleaner, quicker, easier, safer, more scalable, more extensible, more modern alternatives available at this point in time. These will be documented with CGI::Alternatives." - ThisSuitIsBlackNot
Noted your comment re:redirect. I know about CGI.pm obsol. but is there an alternative? I use HTML::Templates for all html output but CGI for cookies, params etc. I have tried the method you susggest too (->redirect). The browser's behaviour is the same. Please note that this problem exits even if all redirects are removed and rather the CGI script outputs some basic HTML to the browser. The browser does not display it at all (e.g. in my example verify script when password is wrong). Can this be related to jQuery? if I comment out the jQuery include, the browser reacts to redirect as expected. - bliako
I have corrected the redirection in my scripts to be using CGI::redirect() rather than with CGI::location() as per ThisSuitIsBlackNot's correct suggestion. The problem still persists. - bliako

1 Answers

0
votes

Adding

data-ajax="false"

to the form definition (e.g. <form data-ajax="false" ....>) inside the file login_page.html

solves the problem. Now browser's url textbox and content area are updated properly when doing a CGI::redirect().

Will this break something else? Who knows.