| <section id="session_package"> |
| <title>Session Package</title> |
| <section> |
| <title>Introduction</title> |
| <para> |
| This is session management code. It provides an interface |
| to allow you to generate and track a browser's visit as a |
| "session", giving you a unique session ID and an interface |
| for storing and retrieving data for that session on the |
| server. |
| </para> |
| |
| <para> |
| This is an alpha/beta release -- documentation is not in |
| final form, but everything you need should be in this file. |
| </para> |
| |
| <para> |
| Using sessions and their included ability to store and |
| retrieve session-related data on the server, programmers can |
| generate more secure and higher-performance websites. For |
| example, hidden fields do not have to be included in forms |
| (and the risk of them being manipulated by the user |
| mitigated) since data that would be stored in hidden fields |
| can now be stored in the session cache on the server. Forms |
| are then faster since no hidden data is transmitted -- |
| hidden fields must be sent twice, once in the form to the |
| broswer and once in the response from it. |
| </para> |
| |
| <para> |
| Robust login systems, etc, can be built on top of this code. |
| </para> |
| </section> |
| |
| <section id="requirements"> |
| <title>Requirements</title> |
| <para> |
| Currently has only been tested with Postgresql, MySql and Oracle. |
| All DB interfacing is done through DIO, though, so it |
| should be relatively easy to add support for other |
| databases. |
| </para> |
| </section> |
| |
| <section> |
| <title>Preparing To Use It</title> |
| |
| <para>Create the tables in your SQL server. With Postgres, |
| do a <command>psql www</command> or whatever DB you |
| connect as, then a backslash-i on |
| <filename>session-create.sql</filename></para> |
| |
| <para>(If you need to delete the tables, use <filename>session-drop.sql</filename>)</para> |
| |
| <para>The session code by default requires a DIO handle |
| called <varname>DIO</varname> (the name of which can be |
| overridden). We get it by doing a</para> |
| |
| <programlisting>RivetServerConf ChildInitScript "package require DIO" |
| RivetServerConf ChildInitScript "::DIO::handle Postgresql DIO -user www"</programlisting> |
| |
| </section> |
| |
| <section> |
| <title>Example Usage</title> |
| |
| <para>In your httpd.conf, add:</para> |
| |
| <programlisting>RivetServerConf ChildInitScript "package require Session; Session SESSION"</programlisting> |
| |
| <para> |
| This tells Rivet you want to create a session object named |
| SESSION in every child process Apache creates.</para> |
| |
| <para> |
| You can configure the session at this point using numerous |
| key-value pairs (which are defined later in this doc). |
| Here's a quick example:</para> |
| |
| <programlisting>RivetServerConf ChildInitScript "package require Session; Session SESSION \ |
| -cookieLifetime 120 -debugMode 1"</programlisting> |
| |
| <para> |
| Turn debugging on <option>-debugMode 1</option> to figure |
| out what's going on -- it's really useful, if |
| verbose.</para> |
| |
| <para> |
| In your .rvt file, when you're generating the <HEAD> |
| section: |
| </para> |
| |
| <programlisting>SESSION activate</programlisting> |
| |
| <para> |
| Activate handles everything for you with respect to |
| creating new sessions, and for locating, validating, and |
| updating existing sessions. Activate will either locate |
| an existing session, or create a new one. Sessions will |
| automatically be refreshed (their lifetimes extended) as |
| additional requests are received during the session, all |
| under the control of the key-value pairs controlling the |
| session object. |
| </para> |
| </section> |
| |
| <section> |
| <title>Using Sessions From Your Code</title> |
| |
| <para>The main methods your code will use are:</para> |
| |
| <variablelist> |
| <varlistentry> |
| <listitem> |
| <cmdsynopsis> |
| <command>SESSION</command> <command>id</command> |
| </cmdsynopsis> |
| <para> |
| After doing a <command>SESSION activate</command>, |
| this will return a 32-byte ASCII-encoded random |
| hexadecimal string. Every time this browser comes |
| to us with a request within the timeout period, this |
| same string will be returned (assuming they have |
| cookies enabled). |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term></term> |
| <listitem> |
| <cmdsynopsis> |
| <command>SESSION</command> |
| <command>is_new_session</command> |
| </cmdsynopsis> |
| <para>returns 1 if it's a new session or 0 if it has |
| previously existed (i.e. it's a zero if this request |
| represents a "return" or subsequent visit to a |
| current session.)</para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term></term> |
| <listitem> |
| <cmdsynopsis> |
| <command>SESSION new_session_reason</command></cmdsynopsis> |
| <para> |
| This will return why this request is the first |
| request of a new session, either "no_cookie" saying |
| the browser didn't give us a session cookie, |
| "no_session" indicating we got a cookie but couldn't |
| find it in our session table, or "timeout" where |
| they had a cookie and we found the matching session |
| but the session has timed out. |
| </para> |
| </listitem> |
| </varlistentry> |
| <varlistentry> |
| <term></term> |
| <listitem> |
| <cmdsynopsis> |
| <command>SESSION store</command> |
| <arg><replaceable>packageName</replaceable></arg> |
| <arg><replaceable>key</replaceable></arg> |
| <arg><replaceable>data</replaceable></arg> |
| </cmdsynopsis> |
| <para> |
| Given the name of a package, a key, and some data. |
| Stores the data in the rivet session cache table. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term></term> |
| <listitem> |
| <cmdsynopsis> |
| <command>SESSION fetch</command> |
| <arg><replaceable>packageName</replaceable></arg> |
| <arg><replaceable>key</replaceable></arg> |
| </cmdsynopsis> |
| <para> |
| Given a package name and a key, return the data |
| stored by the store method, or an empty string if |
| none was set. (Status is set to the DIO error that |
| occurred, it can be fetched using the status |
| method.) |
| </para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </section> |
| |
| <section> |
| <title>Session Configuration Options</title> |
| |
| <para>The following key-value pairs can be specified when a |
| session object (like SESSION above) is created:</para> |
| |
| <variablelist> |
| |
| <varlistentry> |
| <term><option>sessionLifetime</option></term> |
| |
| <listitem> |
| <para>how many seconds the session will live for. |
| 7200 == 2 hours |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term>sessionRefreshInterval</term> |
| <listitem> |
| <para> |
| If a request is processed for a browser that |
| currently has a session and this long has elapsed |
| since the session update time was last updated, |
| update it. 900 == 15 minutes. so if at least 15 |
| minutes has elapsed and we've gotten a new request |
| for a page, update the session update time, |
| extending the session lifetime (sessions that are in |
| use keep getting extended). |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term>cookieName</term> |
| <listitem> |
| <para></para> |
| name of the cookie stored on the user's web browser |
| default rivetSession |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry><term>dioObject</term> |
| <listitem> |
| <para> |
| The name of the DIO object we'll use to access the |
| database (default DIO) |
| </para> |
| </listitem></varlistentry> |
| |
| <varlistentry><term>gcProbability</term> |
| <listitem> |
| <para> |
| The probability that garbage collection will occur |
| in percent. (default 1%, i.e. 1)</para></listitem></varlistentry> |
| |
| <varlistentry><term>gcMaxLifetime</term> |
| <listitem><para>the number of seconds after which |
| data will be seen as "garbage" and cleaned up -- |
| defaults to 1 day (86400)</para></listitem></varlistentry> |
| |
| <varlistentry><term>refererCheck</term> |
| <listitem><para>The substring you want to check each |
| HTTP referer for. If the referer was sent by the |
| browser and the substring is not found, the session |
| will be deleted. (not coded yet)</para></listitem></varlistentry> |
| |
| <varlistentry><term>entropyFile</term> <listitem><para>The |
| name of a file that random binary data can be read |
| from. (<filename>/dev/urandom</filename>) Data will |
| be used from this file to help generate a |
| super-hard-to-guess session ID.</para></listitem></varlistentry> |
| |
| <varlistentry><term>entropyLength</term> |
| <listitem><para>The number of bytes which will be |
| read from the entropy file. If 0, the entropy file |
| will not be read (default 0)</para></listitem></varlistentry> |
| |
| <varlistentry><term>scrambleCode</term> <listitem><para> |
| Set the scramble code to something unique for the |
| site or your app or whatever, to slightly increase |
| the unguessability of session ids (default "some |
| random string")</para></listitem></varlistentry> |
| |
| <varlistentry><term>cookieLifetime</term> |
| <listitem><para>The lifetime of the cookie in |
| minutes. 0 means until the browser is closed (I |
| think). (default 0)</para></listitem></varlistentry> |
| |
| <varlistentry><term>cookiePath</term> <listitem><para>The |
| webserver subpath that the session cookie applies to |
| (defaults to |
| <filename>/</filename>)</para></listitem></varlistentry> |
| |
| <!--varlistentry><term>cookieDomain</term> |
| <listitem><para>The domain to set in the session cookie |
| (FIXME - not coded yet)</para></listitem></varlistentry--> |
| |
| <varlistentry><term>cookieSecure</term> |
| <listitem><para>Specifies whether the cookie should |
| only be sent over secure connections, 0 = any, 1 = |
| secure connections only (default |
| 0)</para></listitem></varlistentry> |
| |
| <varlistentry><term>sessionTable</term> |
| <listitem><para>The name of the table that session |
| info will be stored in (default |
| <varname>rivet_session</varname>)</para></listitem></varlistentry> |
| |
| <varlistentry><term>sessionCacheTable</term> |
| <listitem><para>The name of the table that contains |
| cached session data (default |
| <varname>rivet_session_cache</varname>)</para></listitem></varlistentry> |
| |
| <varlistentry><term>debugMode</term> <listitem><para>Set |
| debug mode to 1 to trace through and see the session |
| object do its thing (default 0)</para></listitem></varlistentry> |
| |
| <varlistentry><term>debugFile</term> <listitem><para>The |
| file handle that debugging messages will be written |
| to (default |
| <varname>stdout</varname>) |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| </variablelist> |
| </section> |
| |
| <section> |
| <title>Session Methods</title> |
| |
| <para> |
| The following methods can be invoked to find out |
| information about the current session, store and fetch |
| server data identified with this session, etc: |
| </para> |
| |
| <variablelist> |
| <varlistentry> |
| <term></term> |
| <listitem> |
| <cmdsynopsis> |
| <command>SESSION status</command></cmdsynopsis> |
| <para> |
| Return the status of the last operation |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| |
| <varlistentry> |
| <term></term> |
| <listitem> |
| <cmdsynopsis> |
| <command>SESSION id</command></cmdsynopsis> |
| <para> |
| Get the session ID of the current browser. Returns |
| an empty string if there's no session (will not |
| happen is SESSION activate has been issued.) |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term></term> |
| <listitem> |
| <cmdsynopsis> |
| <command>SESSION new_session_reason</command> |
| </cmdsynopsis> |
| <para> |
| Returns the reason why there wasn't a previous |
| session, either "no_cookie" saying the browser |
| didn't give us a session cookie, "no_session" |
| indicating we got a cookie but couldn't find it in |
| the session table, or "timeout" when we had a cookie |
| and a session but the session had timed out. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term></term> |
| <listitem> |
| <cmdsynopsis> |
| <command>SESSION store</command> |
| <arg><replaceable>packageName</replaceable></arg> |
| <arg><replaceable>key</replaceable></arg> |
| <arg><replaceable>data</replaceable></arg> |
| </cmdsynopsis> |
| <para> |
| Given a package name, a key string, and a data |
| string, store the data in the rivet session |
| cache. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| |
| <varlistentry> |
| <term></term> |
| <listitem> |
| <cmdsynopsis> |
| <command>SESSION fetch</command> |
| <arg><replaceable>packageName</replaceable></arg> |
| <arg><replaceable>key</replaceable></arg> |
| </cmdsynopsis> |
| <para> |
| Given a package name and a key, return the data |
| stored by the store method, or an empty string if |
| none was set. Status is set to the DIO error that |
| occurred, it can be fetched using the status |
| method. |
| </para> |
| </listitem></varlistentry> |
| |
| <varlistentry> |
| <term></term> |
| <listitem> |
| <cmdsynopsis> |
| <command>SESSION delete</command></cmdsynopsis> |
| |
| <para> |
| Given a user ID and looking at their IP address we |
| inherited from the environment (thanks, Apache), |
| remove them from the session table. (the session |
| table is how the server remembers stuff about |
| sessions). If the session ID was not specified the |
| current session is deleted. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term></term> |
| <listitem> |
| <cmdsynopsis> |
| <command>SESSION activate</command></cmdsynopsis> |
| |
| <para> |
| Find and validate the session ID if they have one. |
| If they don't have one or it isn't valid (timed out, |
| etc), create a session and drop a cookie on |
| them. |
| </para> |
| </listitem> |
| </varlistentry></variablelist> |
| </section> |
| |
| <section> |
| <title>Getting Additional Randomness From The Entropy File</title> |
| |
| <programlisting>RivetServerConf ChildInitScript "Session SESSION -entropyFile /dev/urandom \ |
| -entropyLength 10 -debugMode 1"</programlisting> |
| |
| <para> |
| This options say we want to get randomness from an entropy |
| file (random data pseudo-device) of /dev/urandom, to get ten |
| bytes of random data from that entropy device, and to turn |
| on debug mode, which will cause the SESSION object to output |
| all manner of debugging information as it does stuff. This |
| has been tested on FreeBSD and appears to work. |
| </para> |
| </section> |
| </section> |
| |
| |