Version: v0.9.0

Cookies / Sessions

Kalgan provides full support to manage cookie and session objects.

Configuring Cookies

All cookie values can be defined in our settings file. Let's see an example:

...
cookie:
    renew: login
    login_cookie:
        name: id
        max_age: 86400000
        http_only: true
        secure: true
        value:
        expires:
        domain:
        path: /
...

Be aware, we can hard-code these values in our Rust modules as well. Although the former is the recommended way forward, feel free to take the approach that better fits your needs.

Find a description of these fields in the table below:

cookie.renew List of the cookie names to be refreshed on each request. These names must be sepparated by a coma.
cookie.{cookie_name}.name Name of the cookie. Default: Kalgan.
cookie.{cookie_name}.max_age Time in milliseconds for expiration date. Default: 86400000.
cookie.{cookie_name}.http_only Prevent client-side scripts from accessing cookie? Default: true.
cookie.{cookie_name}.secure Only sent cookie over the HTTPS? Default: true.
cookie.{cookie_name}.value Value of the cookie. Default: Kalgan.
cookie.{cookie_name}.expires Specific expiration date.
cookie.{cookie_name}.domain Domain which can receive the cookie.
cookie.{cookie_name}.path URL scope of the cookie. Default: /.

Using Cookies

Kalgan provides the struct kalgan::storage::cookie::Cookie :

#[derive(Debug, Clone)]
pub struct Cookie {
    name: String,
    value: String,
    max_age: usize,
    expires: String,
    domain: String,
    path: String,
    secure: bool,
    http_only: bool
}

We're not going to detail these fields as they are the same we commented on the above table.

Creating cookies

Notice that all the fields in Cookie are private. To set their values we'll have to use the methods commonly known as setters (for example Cookie.set_name("cookie_name") ).

However Kalgan offers as well the method Cookie.set_from_settings() which takes all the cookie parameters defined in our settings file. This is the way forward we should take. Anyway, nothing stops us from keep setting any value after this method.

For example:

use kalgan::http::{ request::Request, response::Response };
use kalgan::storage::cookie::Cookie;

pub(crate) fn foobar(request: &Request) -> Response {
    ...
    let cookie = Cookie::new()
        .set_from_settings("cookie.login_cookie")
        .set_value("Cookie Value");
    ...
}

Finally, to pass the cookie to the browser we must include it in the Response calling the method Response.add_cookie().

For example:

use kalgan::http::{ request::Request, response::Response };
use kalgan::storage::cookie::Cookie;

pub(crate) fn foobar(request: &Request) -> Response {
    ...
    let cookie = Cookie::new();
    ...
    let contents: String = "...";
    Response::new()
        .set_status(200)
        .set_content_type("text/html; charset=UTF-8")
        .set_content_length(contents.len())
        .set_content(&contents)
        .add_cookie(cookie)
}

Notice we can use this method with the shortcuts to create the Response. For example:

use kalgan::http::{ request::Request, response::Response };
use kalgan::storage::cookie::Cookie;

pub(crate) fn foobar(request: &Request) -> Response {
    ...
    let cookie = Cookie::new();
    ...
    render!("foo/foobar.html").add_cookie(cookie)
}

Reading cookies

Kalgan doesn't provide getters to read the values. This is because the cookie is expected to be read just by the browser. However we're going to need to check the cookie value sent by the browser. These values can be access through the struct Request thanks to the method Request.get_cookies(), which returns a key-value collection of cookies.

For example:

use kalgan::http::{ request::Request, response::Response };
use kalgan::storage::cookie::Cookie;

pub(crate) fn foobar(request: &Request) -> Response {
    ...
    let cookies: &HashMap = request.get_cookies();
    let value = cookies["id"];
    ...
}

Configuring Sessions

Session system is based on crate kalgan_cache, which in turn is based on crate redis. Redis is an in-memory key-value database, cache system and message broker.

Therefore, the first we must do is installing Redis in our machine. For this purpose we can see Configuring Redis in the docs.

Once we have Redis up and running, we must configure Kalgan. For this purpose we can see Configuring Cache in the docs.

A session use the value of the cookie sent by the browser. For this reason we must define in the settings file the session along with the cookie above defined.

For example:

...
session:
    backoffice:
        cookie: login_cookie
...

In this example we have defined a session called backoffice which depends on the cookie login_cookie we've been using above.

Using Sessions

Kalgan provides the struct kalgan::storage::session::Session :

pub struct Session {
    cache: Cache,
    cookies: HashMap
}

Find a description of these fields in the table below:

Session.cache The instance of the struct Cache provided by crate kalgan_cache.
Session.cookies The collection of cookies sent by the browser.

Besides, this object count with the following public methods:

Session::new() Creates the instance.
Session.create() Inserts a record with the given value (usually the user data) and the session id as key in Redis database.
Session.destroy() Deletes the record in Redis database for the given session id.
Session.exists() Checks if the session is present in the cookies sent by the browser.
Session.update() Updates the record in Redis with the given value.
Session.get() Gets the session value (usually the user data).

Kalgan really makes easy working with sessions. Create a Session is pretty straightforward.

Let's see and example of how to create a session which in addition stores the user data:

use kalgan::http::{ request::Request, response::Response };
use kalgan::storage::cookie::Cookie;

pub(crate) fn foobar(request: &Request) -> Response {
    ...
    let user model::User = ...
    ...
    let session_id = Session::new(&request).create(serde_json::to_string(&user).unwrap());
    ...
}

However there's one more step we must do: we have to send this value back to the browser (as a cookie). Again, this is pretty simple.

For this purpose we have to use the method Response.add_session() which will create the cookie login_cookie for us with the value of the session_id. For example:

use kalgan::http::{ request::Request, response::Response };
use kalgan::storage::cookie::Cookie;

pub(crate) fn foobar(request: &Request) -> Response {
    ...
    let session_id = ...
    ...
    render!("foo/foobar.html").add_session("backoffice", session_id)
}