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

O Monks,

I have a fairly large and fairly mature open-source CGI app https://github.com/bcrowell/spotter , which I recently converted to using CGI::Application::Plugin::Authentication for logins, since my old login code was buggy. This basically works great, except that it doesn't work in Google Chrome. Strangely enough, it does work in the version of Chromium that is packaged for Ubuntu, even though I would think it was essentially the same codebase as Chrome. The problem seems to be that although my login cookie is being set properly in all other browsers, in Chrome it doesn't get set. The following is what I got by cutting my app down to a minimal example of the difference in behavior:

Bug.cgi:

#!/usr/bin/perl use strict; use WebInterface; WebInterface->new()->run();
WebInterface.pm:
#!/usr/bin/perl use strict; package WebInterface; use base 'CGI::Application'; use CGI::Session; use CGI::Application::Plugin::Authentication; use CGI; WebInterface->authen->config( STORE => ['Cookie', NAME => 'login', SECRET => 'not really so secret', EXPIRY => '1d', ], ); sub setup { my $self = shift; $self->start_mode('my_run_mode'); $self->run_modes([qw/ my_run_mode /]); $self->mode_param('my_run_mode'); } sub my_run_mode { my $self = shift; $self->authen->logout(); CGI::Session->new(); return ''; } 1;
This minimal example is obviously not functional, or even particularly logical (it only logs you out, not in), but it demonstrates the difference in behavior between browsers. If I run it in Chromium, a cookie named "login" shows up. If I run it in Chrome, no cookie shows up. (You can see this in Tools:Developer Tools:Resources:Cookies.) For anyone who wants to try running it, I have it installed here: http://www.lightandmatter.com/cgi-bin/Bug.cgi . You should see that in Firefox, IE, or Chromium, the cookie gets set, but in Chrome it doesn't.

Can anyone suggest what's going on?

Normally I would expect that if a cookie was not getting set, the problem would be that either it wasn't being set with the correct domain, or the expiration date was not in the future. Here the expiration date is being set in the future, and I assume that CGI::Application::Plugin::Authentication bakes it with the correct domain (else it wouldn't work in any browser).

Any thoughts would be much appreciated.

-Ben

Replies are listed 'Best First'.
Re: CGI::Application::Plugin::Authentication not working on Google Chrome
by Anonymous Monk on Mar 12, 2013 at 06:18 UTC

    Can anyone suggest what's going on?

    Browsers are free to ignore cookies, make them temporary (duration of browsing session), keep them forever even after being instructed to delete them , even decide what to do based on P3P or some random heuristic

    If it works on one popular browser, chances are the correct headers are being generated, which means this is likely due to a GoogleChrome setting/plugin/whatever ... maybe even a bug

    So check the headers manually, check for updates, try with a fresh profile (if chrome has such a thing like firefox does), check the settings ... I can't help with specifics i don't use chrome

Re: CGI::Application::Plugin::Authentication not working on Google Chrome
by scorpio17 (Canon) on Mar 12, 2013 at 15:24 UTC

    I have a bunch of web apps that use CGI::Application::Plugin::Authentication and they all function correctly with the latest versions of IE, FireFox, and Chrome on Win7, WinXP, and Ubuntu (10.04LTS and 12.04LTS).

    SO... I hate to say it, but there's probably a bug in your code, not in the module. You shouldn't need to, for example, specifically call CGI::Session->new() in your run mode... I know you're only trying to reproduce the problem, but that looks weird. Assuming that you're also using CGI::Application::Plugin::Session, you only need to use $self->session(). And, assuming that your sessions are stored in a database back end, you should also be using CGI::Application::Plugin::DBH. Configuring these three to play nice with each other can be a little tricky.

    Here's a link to a simple login tutorial I wrote a long time ago:
    RFC: Proposed tutorial - simple login script using CGI::Application

    Compare your code to my demo, especially the part that initializes the session module and the authorization module and see if you can spot any differences. That should help get you started.

    Good luck!

      Aha -- the combination of your reply and Anonymous Monk's did the trick. I examined the headers directly and got this:
      $ ./Bug.pl Set-Cookie: login=Yz1jamd1SEMxYm43MHJsNDQramdTUDZFREJPUlU%3D; path=/; +expires=1d Date: Tue, 12 Mar 2013 15:24:49 GMT Content-Type: text/html; charset=ISO-8859-1
      The "expires" string should be an actual date string, not the offset "1d." The problem was that the offset needed to be "+1d," as shown in your example. I then get this:
      $ ./Bug.pl Set-Cookie: login=Yz1jamd1SEMxYm43MHJsNDQramdTUDZFREJPUlU%3D; path=/; +expires=Wed, 13-Mar-2013 15:34:59 GMT Date: Tue, 12 Mar 2013 15:34:59 GMT Content-Type: text/html; charset=ISO-8859-1
      Apparently most browsers accept a malformed "expires" value and make the cookie a session cookie as a result, but chrome doesn't accept such a cookie at all.