[cgiapp] CAP::Authentication not working properly with CAP::Session

Richard Jones ra.jones at dpw.clara.co.uk
Thu Nov 20 17:20:52 EST 2008


Bradley C Bailey wrote:
> Richard,
> 
>> Hope someone can help with this. I'm having a major headache with 
>> authentication and sessions.
[..]

>> In the CGI::Session docs there is a mention of session->flush, and if 
>> I use this in teardown(), then sessions do start to work, providing I 
>> use $self->session_delete after logout. Odd because I've never had to 
>> use session->flush before.
> 
> What kind of environment are you using?

Development = CA::Server. Production and periodic testing = 
Apache/mod_perl. So both persistent. But I also get the same behaviour 
with the test scripts running under Test::WWW::Mechanize::CGIApp, which 
  I presume isn't persistent. And I run other cgiapps under mod_perl 
without needing to call flush, and have tested them on the same dev 
platform as my current app.

> Sessions are supposed to automatically flush() when they go out of scope 
> and are DESTROYed.  I have never had to explicitly call flush().  If you 
> are using some kind of persistent environment (ie: mod_perl, FastCGI, 
> ...) make sure something isn't keeping the session around.

How would I go about determining whether the session *is* being retained?

>> But I'm also trying to use CAP::Flash, and find the flash message 
>> never gets written to the session (even though flash->dump shows it's 
>> present in the flash object), unless I use flash->flush in teardown(). 
>> But then the message gets converted to 'keep' and never goes away.
>> All this suggests to me there is something wrong with the way 
>> CGI::Session / CAP::Session is working, but I can't put my finger on 
>> anything obvious, after several days trying. Does anyone recognise 
>> this behaviour or can explain it?
> 
> Probably related to the same issue as above, with objects not going out 
> of scope and getting cleaned up.

Yes, I assumed it was related.

> Flash->flush() is a bit different than session->flush().  If you really 
> need to put this code in teardown(), first call flash->cleanup() then 
> flash->flush().  cleanup() goes through and marks data for removal, 
> flush() writes it to the session.  This is all supposed to happen during 
> DESTROY() as though, so it should be unnecessary.

Well, I've more-or-less got flash working now without flush, but not 
with CAP::Flash but CGI::Session::Flash. It uses a method in the base 
controller (superclass) which just returns a new CGI::Session::Flash 
object each time it's called. For setting ($self->flash->set) I found I 
could stash the Flash object and return it for any subsequent calls, but 
not for the get stage. That stage is done in the template (CAP::TT) with:

[% SET flash = c.flash %]
[% FOREACH type IN [ 'INFO', 'WARNING', 'ERROR' ] %]
   [% IF flash.has_key(type) %]
     <p>[% flash.get(type) %]</p>, etc

You might recognise that - it's based on the CAP::Flash pod. This call 
to c.flash *has* to return a new Flash object, not a stashed one.

I get the impression only 1 'get' call to the session flash is 
permitted, after that it's cleared. So for example this doesn't work:

[% FOREACH type IN [ 'INFO', 'WARNING', 'ERROR' ] %]
   [% IF c.flash.has_key(type) %]
     <p>[% c.flash.get(type) %]</p>, etc

Only the first 'type' (INFO in this case) gets printed, even though in a 
test script I put all 3 in.

I don't know how much resource overhead I incur creating a new Flash 
object for each 'set' and one for the 'get', but so far that is the only 
way I could get flash working. I've still no idea why this way works and 
CAP::Flash doesn't, but it's likely to be related to the general 
sessions flakiness in my current app.

> Also, just curious, if you take CAP::Flash completely out of the picture 
> does your session problem go away?

No, just the same - I still need to call flush() in teardown.
-- 
Richard Jones


More information about the cgiapp mailing list