Form-Based Authentication
One of the drawbacks of HTTP authentication is that the user can't easily sign
out without closing the browser window. A form and cookie based solution is
therefore preferable for most web applications.
With this method if the user accesses a page that returns a 401 status code, the
AuthKit middleware intercepts it and displays a form for the user to sign in.
The template to use is supplied when configuring the middleware or a default is
used if none is specified. If the user's sign in is incorrect they are shown
the form again.
Since the authentication form is submitted (via POST) neither the PATH_INFO nor
the QUERY_STRING are accessed, and hence the current path remains _unaltered_
through the entire authentication process. If authentication succeeds, the
REQUEST_METHOD is converted from a POST to a GET and the page the user was
trying to view is displayed, so that a redirect is unnecessary (unlike most
form auth implementations).
Here is a working example:
System Message: ERROR/3 (<string>, line 22)
Unknown directive type "Python".
.. Python ::
from authkit.authenticate import middleware, sample_app
app = middleware(
sample_app,
setup_method='form,cookie',
cookie_secret='secret encryption string',
form_authenticate_user_data = """
Username1:password1
username2:password2
""",
cookie_signoutpath = '/signout',
#cookie_params_name = 'test'
)
if __name__ == '__main__':
from paste.httpserver import serve
serve(app, host='0.0.0.0', port=8080)
The form method can use the same valid() authenticate function as that
used by the HTTP basic method but this example uses an alternative method
making use of the AuthKit user management API. This is described in detail
later but provides a very quick and easy way of specifying users, passwords,
groups and roles.
The example also specifies a cookie_secret which is a string used to help
make the encryption on the cookie more random and a cookie_signout
parameter which is a special path which should automatically sign the user out
when visited but will still display the resulting page so that your application
can display a signed out message. There are lots of cookie options you can
specify including the name, and expire time and more. These are all described
in the cookie options section later.
If you run the example and visiting http://localhost:8080/private the sign in
form will be displayed. If you sign in with a username that is the same as the
password you will be signed in. If you visit http://localhost:8080/signout you
will see the data as usual but if you press refresh you will notice that you
have also been signed out.
Note
If you would like your application to handle the creation of the form, the
sign in process and sign out manually so that you have complete control over
the authentication process you should use the forward method.
You can also configure the template used in the form. There are three ways to
do this. The first is to specify the form_template option with the new
template.
The template should contain the characters %s which will be replaced with
the correct action URL. Any other % characters should be escaped by
writing them as %%. The form should also contain fields named username
and password and should use the POST method. Here is an example:
form_template = """\
<html>
<head><title>Please Login!</title></head>
<body>
<h1>Please Login</h1>
<form action="%s" method="post">
<dl>
<dt>Username:</dt>
<dd><input type="text" name="username"></dd>
<dt>Password:</dt>
<dd><input type="password" name="password"></dd>
</dl>
<input type="submit" name="authform" />
<hr />
</form>
</body>
</html>
"""
You can also specify form_template_file which should be a file containing
the template with the same escaping as described above or form_template_obj
which should be the Paste eval_import style path to a string object in an
existing module containing the template or a callable that returns a string.
For example:
form_template_obj = authkit.authenticate.form:template