pavex_session/config/cookie.rs
1use pavex::cookie::SameSite;
2
3#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
4#[serde(rename_all = "snake_case")]
5#[non_exhaustive]
6/// Configure the cookie used to store session information on the client-side.
7pub struct SessionCookieConfig {
8 /// The name of the cookie used to store the session ID.
9 ///
10 /// By default, the name is set to `id`.
11 #[serde(default = "default_session_cookie_name")]
12 pub name: String,
13 /// Set the `Domain` attribute on the cookie used to store the session ID.
14 ///
15 /// By default, the attribute is not set.
16 #[serde(default)]
17 pub domain: Option<String>,
18 /// Set the `Path` attribute on the cookie used to store the session ID.
19 ///
20 /// By default, the attribute is set to `/`.
21 #[serde(default = "default_session_cookie_path")]
22 pub path: Option<String>,
23 /// Set the `Secure` attribute on the cookie used to store the session ID.
24 ///
25 /// If the cookie is marked as `Secure`, it will only be transmitted when the connection is secure (e.g. over HTTPS).
26 ///
27 /// Default is `true`.
28 #[serde(default = "default_session_cookie_secure")]
29 pub secure: bool,
30 /// Set the `HttpOnly` attribute on the cookie used to store the session ID.
31 ///
32 /// If the cookie is marked as `HttpOnly`, it will not be visible to JavaScript
33 /// snippets running in the browser.
34 ///
35 /// Default is `true`.
36 #[serde(default = "default_session_cookie_http_only")]
37 pub http_only: bool,
38 /// Set the [`SameSite`] attribute on the cookie used to store the session ID.
39 ///
40 /// By default, the attribute is set to [`SameSite::Lax`].
41 #[serde(default = "default_session_cookie_same_site")]
42 pub same_site: Option<SameSite>,
43 /// The kind of session cookie to use.
44 ///
45 /// By default, it is set to [`SessionCookieKind::Persistent`].
46 #[serde(default)]
47 pub kind: SessionCookieKind,
48}
49
50impl Default for SessionCookieConfig {
51 fn default() -> Self {
52 Self {
53 name: default_session_cookie_name(),
54 domain: None,
55 path: default_session_cookie_path(),
56 secure: default_session_cookie_secure(),
57 http_only: default_session_cookie_http_only(),
58 same_site: default_session_cookie_same_site(),
59 kind: Default::default(),
60 }
61 }
62}
63
64fn default_session_cookie_name() -> String {
65 // See https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html#session-id-name-fingerprinting
66 "id".to_string()
67}
68
69fn default_session_cookie_secure() -> bool {
70 true
71}
72
73fn default_session_cookie_http_only() -> bool {
74 true
75}
76
77fn default_session_cookie_path() -> Option<String> {
78 Some("/".to_string())
79}
80
81fn default_session_cookie_same_site() -> Option<SameSite> {
82 Some(SameSite::Lax)
83}
84
85/// The kind of cookie used to store session information on the client-side.
86#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
87#[serde(rename_all = "snake_case")]
88#[non_exhaustive]
89pub enum SessionCookieKind {
90 /// A persistent session cookie.
91 ///
92 /// The cookie will be stored on the client's device with an
93 /// expiration date set by the server via the `Max-Age` attribute.
94 ///
95 /// This is the default.
96 #[default]
97 Persistent,
98 /// A cookie that expires when the browser session ends.
99 ///
100 /// Each browser has its own concept of "browser session", e.g. the session
101 /// doesn't necessarily end when the browser window or tab is closed.
102 /// For example, both Firefox and Chrome automatically restore the session
103 /// when the browser is restarted, keeping all session cookies alive.
104 /// Consider using [`SessionCookieKind::Persistent`]
105 /// if you don't want to deal with the nuances of browser-specific behaviour.
106 Session,
107}