Adding sessions is straightforward:
let () =
Dream.run
@@ Dream.logger
@@ Dream.memory_sessions ()
@@ fun request ->
match Dream.session_field request "user" with
| None ->
let%lwt () = Dream.invalidate_session request in
let%lwt () = Dream.set_session_field request "user" "alice" in
Dream.html "You weren't logged in; but now you are!"
| Some username ->
Printf.ksprintf
Dream.html "Welcome back, %s!" (Dream.html_escape username)$ cd example/b-session
$ opam install --deps-only --yes .
$ dune exec --root . ./session.exeThe first time you access the app, it “logs you in” by saving you user name in
a session. The session manager,
Dream.memory_sessions,
a middleware, adds a dream.session cookie to the response, containing the
session key. The next time you access the app, the session is looked up again
by this key, and the app recognizes you as logged in!
The default sessions provided by Dream contain string-to-string maps (dicts). In this example, we created
{
"user": "alice"
}
Dream.memory_sessions
stores sessions in server memory only. This is great for development, because
you don't have to worry about a database or a secret key. But it means that all
session data is lost when the server is restarted. For example, if your Web app
logs in users, server restart will log all users out.
There are two other session back ends, which are persistent:
Dream.cookie_sessionsstores session data in encrypted cookies. That is, session data is stored on clients, rather than on the server. You can replaceDream.memory_sessionswithDream.cookie_sessionsand it will work right away (except thatDream.cookie_sessionsdon't require a call withunit). However, if you want to be able to decrypt sessions set by previous runs of the server, use theDream.set_secretmiddleware beforeDream.cookie_sessions. If you don't, the server will be using a different random encryption key each time it starts.Dream.sql_sessionsstores sessions in a database. It is shown in exampleh-sql.
All requests passing through a session middleware get assigned a session. If
they don't have a dream.session cookie, or the cookie is invalid, they get a
fresh, empty session, also known as a pre-session.
If you log in a user, grant a user or session any enhanced access rights, or
similar, be sure to replace the existing session with a new one by calling
Dream.invalidate_session.
This helps to mitigate
session fixation attacks. The
new session will, again, be an empty pre-session.
It is best to use HTTPS when using sessions, to prevent session cookies from
being easily observed by third parties. See
Dream.run argument ~https, and
example l-https. If you redirect from HTTP to HTTPS,
do not issue sessions for HTTP requests. If you do, don't accept them later
from HTTPS requests.
Next steps:
- Sessions already use cookies internally, but in
c-cookiewe set cookies for our own purposes! d-formbuilds secure forms on top of sessions.
