The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


Apache::AxKit::Plugin::Session - flexible session management for AxKit


Basic configuration

This is the quickstart:

    AxAddPlugin Apache::AxKit::Plugin::Session

Put it in .htaccess or httpd.conf. That's all. Easy, huh?

Now some alternatives:

The above line only applies to AxKit documents - usually the right thing. To get sessions for all files, use:

    PerlFixupHandler Apache::AxKit::Plugin::Session

The above variants need cookies enabled. Visitors that disable them are honestly screwed. But there is rescue: Get automatic fallback to URL-Encoded session IDs:

    PerlModule Apache::AxKit::Plugin::Session

    AuthType Apache::AxKit::Plugin::Session
    AuthName AxKitSession

    PerlAuthenHandler Apache::AxKit::Plugin::Session->authenticate
    PerlAuthzHandler Apache::AxKit::Plugin::Session->authorize
    require valid-user

(That _must_ be in httpd.conf)

Note that URL-encoded session IDs are generally regarded bad style and can create a huge security risk. Used carefully it can mean an enhancement for your customers. That said, URL sessions are deprecated. There is a different solution under development.

So, now we made it through basic configuration. Let's try...

Protecting some documents

To do so, we first need to silence apache's internal authorization:

    AuthType Apache::AxKit::Plugin::Session
    AuthName AxKitSession
    PerlAuthenHandler Apache::AxKit::Plugin::Session->authenticate
    PerlAuthzHandler Apache::AxKit::Plugin::Session->authorize

Then we can do:

    require user admin

Put that into a .htaccess, or in a <Location> section, or similar.

But how can user admin log in? Want a login screen when privileges don't suffice?

    ErrorDocument 403 /login.xsp

login.xsp must call <auth:login>, see AxKit::XSP::Auth.

Advanced protection:

Allow access to user JohnDoe and to user JaneDoe:

        require user JohnDoe JaneDoe

Allow access to members of group internal and mambers of group admin:

        require group internal admin

Allow access to members with level 42 or higher:

        require level 42

Allow access to all users except guest:

        require not user guest

Allow access to all users who are in group powerusers AND either longtimeusers or verylongtimeusers (compare "group" above):

        require combined group powerusers group "longtimeusers verylongtimeusers"

Allow access if (group == longtimeusers AND (group == powerusers OR level >= 10))

        require combined group longtimeusers alternate "group powerusers level 10"

You can have as many "require" lines as you want. Access is granted if at least one rule matches.

Advanced options

How long is a session valid when idle? (minutes, must be multiple of 5)

    PerlSetVar AxKitSessionExpire 30

Which session module should be used?

    PerlSetVar AxKitSessionManager Apache::Session::File

Where should session files (data and locks) go?

    PerlSetVar AxKitSessionDir /tmp/sessions

Do you want global data? ($r->pnotes('GLOBALS') and AxKit::XSP::Globals)

    PerlSetVar AxKitSessionGlobal Tie::SymlinkTree,/tmp/globals

How's the "guest" user called?

    PerlSetVar AxKitSessionGuest guest

Want to check the IP address for sessions?

    PerlSetVar AxKitSessionIPCheck 1

Beware that IP checking is dangerous: Some people have different IP addresses for each request, AOL customers for example. There are several values for you to choose: 0 = no check; 1 = use numeric IP address or X-Forwarded-For, if present; 2 = use numeric IP address with last part stripped (/24 subnet); 3 = use numeric IP address

Look at Apache::Cookie. You'll quickly get the idea:

    PerlSetVar AxKitSessionPath /
    PerlSetVar AxKitSessionExpires +1d
    PerlSetVar AxKitSessionDomain some.domain
    PerlSetVar AxKitSessionSecure 1

Path can only be set to "/" if using URL sessions. Do not set "AxKitSessionExpires", since the default value is best: it keeps the cookies until the user closes his browser.

Disable cookies: (force URL-encoded sessions)

    PerlSetVar AxKitSessionNoCookie 1

Internal options

DANGER! Do not fiddle with these unless you know what you are doing.

Want a different redirector location? (default is '/redirect')

    <Perl>$Apache::AxKit::Plugin::Session::redirect_location = "/redir";</Perl>


    PerlSetVar AxDebugSession 5

Prefix to session ID in URLs:

    PerlSetVar SessionPrefix Session-


WARNING: This version is for AxKit 1.7 and above!

This module is an authentication and authorization handler for Apache, designed specifically to work with Apache::AxKit. It should be generic enough to work without it as well, only much of its comfort lies in a separate XSP taglib which is distributed alongside this module. It combines authentication and authorization in Apache::AuthCookieURL style with session management via one of the Apache::Session modules. It should even work with Apache::Session::Counted. See those manpages for more information, but be sure to note the differences in configuration!

In addition to Apache::AuthCookieURL, you get:

  • session data in $r->pnotes('SESSION')

  • global application data in $r->pnotes('GLOBAL')

  • sessions without the need to login (guest account)

  • automatic expiration of sessions after 30 minutes (with automatic degradation to guest account, if any)

  • remote ip check of sessions, for a tiny bit more security

  • authorization based on users, groups or levels, including logical AND, OR and NOT of any requirement

  • great AxKit taglibs for retrieving, checking and changing most settings

To use authentication, you have to provide a login page which displays a login form, verifies the values and calls <auth:login> (assuming XSP). Logout pages work via <auth:logout>. Both functions are provided in the Auth XSP taglib, see AxKit::XSP::Auth for details.


This module is extremely customizable. Please skip this section until you have the module up and running. This section is only for advanced usage.

Perl interface

Authorization via user name works by comparing the user name given at login time: Apache::AxKit::Plugin::Session->login($r,$user_name)

Authorization via groups and levels works by using 2 session variables:

  • $r->pnotes('SESSION')->{'auth_access_groups'} is a hash which contains an element for each group the user is in. The value associated with that key is ignored, use undef if you have no other use for that value. Nested groups have to be handled by manually adding subgroups to this hash. Access is granted if any of the given groups are present in this hash. (i.e., logical OR)

  • $r->pnotes('SESSION')->{'auth_access_level'} is a numeric level which must be or equal to the required level to be granted access. No value at all means 'do not grant access if any level is required'.

Note that the session dir will always leak. You will have to do manual cleanup, since automatic removal of old session records is only possible in some cases. The distribution tarball contains an example script to do that.


See the synopsis for an overview and quick explanation.

All settings are set with PerlSetVar and may occur in any location PerlSetVar is allowed in, except SessionPrefix, which must be a global setting.

  • SessionPrefix, AxKitSessionCache, AxKitSessionLoginScript, AxKitSessionLogoutURI, AxKitSessionNoCookie, AxKitSession(Path|Expires|Domain|Secure)

    These settings are similar to Apache::AuthCookieURL. Some of them are very advanced and probably not needed at all. Some may be broken by now. Please only use the documented variables shown in the synopsis.

  • AxKitSessionExpire

    Sets the session expire timeout in minutes. The value must be a multiple of 5.

    Example: PerlSetVar AxKitSessionExpire 30

    Note that the session expire timeout (AxKitSessionExpire) is different from the cookie expire timeout (AxKitSessionExpires). You should not set the cookie expire timeout unless you have a good reason to do so.

  • AxKitSessionManager

    Specifies the module to use for session handling. Directly supported are File, DB_File, Counted, and all DB server modules if connecting anonymously. For all other configurations (including Flex), you need AxKitSessionManagerArgs, too.

    Example: PerlSetVar AxKitSessionManager Apache::Session::Counted

  • AxKitSessionManagerArgs

    List of additional session manager parameters in the form: Name Value. Use with PerlAddVar.

    Example: PerlAddVar AxKitSessionManagerArgs User foo

  • AxKitSessionDir

    The location where all session files go, including lockfiles. If you are using a database server as session backend, this is the server specific db/table string.

    Example: PerlSetVar AxKitSessionDir /home/sites/site42/data/session

  • AxKitSessionGuest

    The user name to be recognized as guest account. Setting this to a false value (the default) disables automatic guest login. If logins are used at all, this is the only way to get session management for unknown users. If no logins are used, this MUST be set to some value.

    Example: PerlSetVar AxKitSessionGuest guest

  • AxKitSessionGlobal

    Often you want to share a few values across all sessions. That's what $r->pnotes('GLOBALS') is for: It works just like the session hash, but it is shared among all sessions. In previous versions, globals were always available, but since many users didn't care and there were grave problems in the old implementation, behaviour has changed: You get a fake GLOBALS hash unless you specify the sotrage method to use using this setting. It takes a comma-separated list of "tie" parameters, starting with the name of the module to use. Do not use spaces, and you should use a module that works with a minimum of locking, like Tie::SymlinkTree. Otherwise, you could get server lockups or bad performance (which is what you often got in previous versions as well).

    Example: PerlSetVar AxKitSessionGlobal Tie::SymlinkTree,/tmp/globals

  • AxKitSessionIPCheck

    The level of IP matching in sessions. A session id is only valid when the connection is coming from the same remote address. This setting lets you adjust what will be checked: 0 = nothing, 1 = numeric IP address or HTTP X-Forwarded-For header, if present, 2 = numeric IP address with last part stripped off, 3 = whole numeric IP address.

    Example: PerlSetVar AxKitSessionIPCheck 3

Programming interface

By subclassing, you can modify the authorization scheme to your hearts desires. You can store directory and file permissions in an RDBMS and you can invent new permission types.

To store and retrieve permissions somewhere else than in httpd.conf, override 'get_permissions' and 'set_permissions'. 'get_permissions' should return a list of arrayrefs, each one containing a (type,argument-string) pair (e.g., the equivalent of a 'require group foo bar' would be ['group','foo bar']). Access is granted if one of these requirements are met. 'set_permissions' should store such a list somewhere, if dynamic modification of permissions is wanted. For more details, read the source.

For a new permission type 'foo', provide 3 subs: 'foo', 'pack_requirements_foo' and 'unpack_requirements_foo'. sub 'foo' should return OK or FORBIDDEN depending on the parameters and the session variable 'auth_access_foo'. The other two subs can be aliased to 'default_(un)pack_requirements' if your 'require foo' parses like a 'require group'. Read the source for more information.


URL munging has security issues. Session keys can get written to access logs, cached by browsers, leak outside your site, and can be broken if your pages use absolute links to other pages on-site (but there is HTTP Referer: header tracking for this case). Keep this in mind.

The redirect handler tries to catch the case of external redirects by changing them into self-refreshing pages, thus removing a possibly sensitive http referrer header. This won't work from mod_perl, so use Apache::AuthCookieURL's fixup_redirect instead. If you are adding hyperlinks to your page, change to /redirect?url=


Apache::Session, AxKit 1.7, mod_perl 1.2x


Jörg Walter <>.




Apache::AuthCookie, Apache::AuthCookieURL, Apache::Session, Apache::Session::File, Apache::Session::Counted, AxKit::XSP::Session, AxKit::XSP::Auth, AxKit::XSP::Globals, Tie::SymlinkTree

1 POD Error

The following errors were encountered while parsing the POD:

Around line 1660:

Non-ASCII character seen before =encoding in 'Jörg'. Assuming UTF-8