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)
}