mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-27 17:22:57 +01:00
add some doc examples to -session
This commit is contained in:
parent
bad6159516
commit
a325f5dd02
@ -1,13 +1,14 @@
|
|||||||
//! Configuration options to tune the behaviour of [`SessionMiddleware`].
|
//! Configuration options to tune the behaviour of [`SessionMiddleware`].
|
||||||
|
|
||||||
use actix_web::cookie::{time::Duration, Key, SameSite};
|
use actix_web::cookie::{time::Duration, Key, SameSite};
|
||||||
|
use derive_more::From;
|
||||||
|
|
||||||
use crate::{storage::SessionStore, SessionMiddleware};
|
use crate::{storage::SessionStore, SessionMiddleware};
|
||||||
|
|
||||||
/// Determines what type of session cookie should be used and how its lifecycle should be managed.
|
/// Determines what type of session cookie should be used and how its lifecycle should be managed.
|
||||||
///
|
///
|
||||||
/// Used by [`SessionMiddlewareBuilder::session_lifecycle`].
|
/// Used by [`SessionMiddlewareBuilder::session_lifecycle`].
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, From)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum SessionLifecycle {
|
pub enum SessionLifecycle {
|
||||||
/// The session cookie will expire when the current browser session ends.
|
/// The session cookie will expire when the current browser session ends.
|
||||||
@ -27,18 +28,6 @@ pub enum SessionLifecycle {
|
|||||||
PersistentSession(PersistentSession),
|
PersistentSession(PersistentSession),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<BrowserSession> for SessionLifecycle {
|
|
||||||
fn from(session: BrowserSession) -> Self {
|
|
||||||
Self::BrowserSession(session)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<PersistentSession> for SessionLifecycle {
|
|
||||||
fn from(session: PersistentSession) -> Self {
|
|
||||||
Self::PersistentSession(session)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A [session lifecycle](SessionLifecycle) strategy where the session cookie expires when the
|
/// A [session lifecycle](SessionLifecycle) strategy where the session cookie expires when the
|
||||||
/// browser's current session ends.
|
/// browser's current session ends.
|
||||||
///
|
///
|
||||||
@ -46,6 +35,9 @@ impl From<PersistentSession> for SessionLifecycle {
|
|||||||
/// continue running in the background when the browser is closed—session cookies are not deleted
|
/// continue running in the background when the browser is closed—session cookies are not deleted
|
||||||
/// and they will still be available when the browser is opened again. Check the documentation of
|
/// and they will still be available when the browser is opened again. Check the documentation of
|
||||||
/// the browsers you are targeting for up-to-date information.
|
/// the browsers you are targeting for up-to-date information.
|
||||||
|
///
|
||||||
|
/// Due to its `Into<SessionLifecycle>` implementation, a `BrowserSession` can be passed directly
|
||||||
|
/// to [`SessionMiddlewareBuilder::session_lifecycle()`].
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct BrowserSession {
|
pub struct BrowserSession {
|
||||||
state_ttl: Duration,
|
state_ttl: Duration,
|
||||||
@ -103,6 +95,26 @@ impl Default for BrowserSession {
|
|||||||
/// Persistent cookies have a pre-determined expiration, specified via the `Max-Age` or `Expires`
|
/// Persistent cookies have a pre-determined expiration, specified via the `Max-Age` or `Expires`
|
||||||
/// attribute. They do not disappear when the current browser session ends.
|
/// attribute. They do not disappear when the current browser session ends.
|
||||||
///
|
///
|
||||||
|
/// Due to its `Into<SessionLifecycle>` implementation, a `PersistentSession` can be passed directly
|
||||||
|
/// to [`SessionMiddlewareBuilder::session_lifecycle()`].
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// use actix_web::cookie::time::Duration;
|
||||||
|
/// use actix_session::SessionMiddleware;
|
||||||
|
/// use actix_session::config::{PersistentSession, TtlExtensionPolicy};
|
||||||
|
///
|
||||||
|
/// const SECS_IN_WEEK: i64 = 60 * 60 * 24 * 7;
|
||||||
|
///
|
||||||
|
/// // a session lifecycle with a time-to-live (expiry) of 1 week and default extension policy
|
||||||
|
/// PersistentSession::default().session_ttl(Duration::seconds(SECS_IN_WEEK));
|
||||||
|
///
|
||||||
|
/// // a session lifecycle with the default time-to-live (expiry) and a custom extension policy
|
||||||
|
/// PersistentSession::default()
|
||||||
|
/// // this policy causes the session state's TTL to be refreshed on every request
|
||||||
|
/// .session_ttl_extension_policy(TtlExtensionPolicy::OnEveryRequest);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// [persistent]: https://www.whitehatsec.com/glossary/content/persistent-session-cookie
|
/// [persistent]: https://www.whitehatsec.com/glossary/content/persistent-session-cookie
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct PersistentSession {
|
pub struct PersistentSession {
|
||||||
@ -113,10 +125,10 @@ pub struct PersistentSession {
|
|||||||
impl PersistentSession {
|
impl PersistentSession {
|
||||||
/// Specifies how long the session cookie should live.
|
/// Specifies how long the session cookie should live.
|
||||||
///
|
///
|
||||||
/// Defaults to 1 day if left unspecified.
|
|
||||||
///
|
|
||||||
/// The session TTL is also used as the TTL for the session state in the storage backend.
|
/// The session TTL is also used as the TTL for the session state in the storage backend.
|
||||||
///
|
///
|
||||||
|
/// Defaults to 1 day.
|
||||||
|
///
|
||||||
/// A persistent session can live more than the specified TTL if the TTL is extended.
|
/// A persistent session can live more than the specified TTL if the TTL is extended.
|
||||||
/// See [`session_ttl_extension_policy`](Self::session_ttl_extension_policy) for more details.
|
/// See [`session_ttl_extension_policy`](Self::session_ttl_extension_policy) for more details.
|
||||||
pub fn session_ttl(mut self, session_ttl: Duration) -> Self {
|
pub fn session_ttl(mut self, session_ttl: Duration) -> Self {
|
||||||
@ -127,7 +139,7 @@ impl PersistentSession {
|
|||||||
/// Determines under what circumstances the TTL of your session should be extended.
|
/// Determines under what circumstances the TTL of your session should be extended.
|
||||||
/// See [`TtlExtensionPolicy`] for more details.
|
/// See [`TtlExtensionPolicy`] for more details.
|
||||||
///
|
///
|
||||||
/// Defaults to [`TtlExtensionPolicy::OnStateChanges`] if left unspecified.
|
/// Defaults to [`TtlExtensionPolicy::OnStateChanges`].
|
||||||
pub fn session_ttl_extension_policy(
|
pub fn session_ttl_extension_policy(
|
||||||
mut self,
|
mut self,
|
||||||
ttl_extension_policy: TtlExtensionPolicy,
|
ttl_extension_policy: TtlExtensionPolicy,
|
||||||
@ -148,23 +160,23 @@ impl Default for PersistentSession {
|
|||||||
|
|
||||||
/// Configuration for which events should trigger an extension of the time-to-live for your session.
|
/// Configuration for which events should trigger an extension of the time-to-live for your session.
|
||||||
///
|
///
|
||||||
/// If you are using a [`BrowserSession`], `TtlExtensionPolicy` controls how often the TTL of
|
/// If you are using a [`BrowserSession`], `TtlExtensionPolicy` controls how often the TTL of the
|
||||||
/// the session state should be refreshed. The browser is in control of the lifecycle of the
|
/// session state should be refreshed. The browser is in control of the lifecycle of the session
|
||||||
/// session cookie.
|
/// cookie.
|
||||||
///
|
///
|
||||||
/// If you are using a [`PersistentSession`], `TtlExtensionPolicy` controls both the expiration
|
/// If you are using a [`PersistentSession`], `TtlExtensionPolicy` controls both the expiration of
|
||||||
/// of the session cookie and the TTL of the session state.
|
/// the session cookie and the TTL of the session state on the storage backend.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum TtlExtensionPolicy {
|
pub enum TtlExtensionPolicy {
|
||||||
/// The TTL is refreshed every time the server receives a request associated with a session.
|
/// The TTL is refreshed every time the server receives a request associated with a session.
|
||||||
///
|
///
|
||||||
/// # Performance impact
|
/// # Performance impact
|
||||||
/// Refreshing the TTL on every request is not free.
|
/// Refreshing the TTL on every request is not free. It implies a refresh of the TTL on the
|
||||||
/// It implies a refresh of the TTL on the session state. This translates into a request over
|
/// session state. This translates into a request over the network if you are using a remote
|
||||||
/// the network if you are using a remote system as storage backend (e.g. Redis).
|
/// system as storage backend (e.g. Redis). This impacts both the total load on your storage
|
||||||
/// This impacts both the total load on your storage backend (i.e. number of
|
/// backend (i.e. number of queries it has to handle) and the latency of the requests served by
|
||||||
/// queries it has to handle) and the latency of the requests served by your server.
|
/// your server.
|
||||||
OnEveryRequest,
|
OnEveryRequest,
|
||||||
|
|
||||||
/// The TTL is refreshed every time the session state changes or the session key is renewed.
|
/// The TTL is refreshed every time the session state changes or the session key is renewed.
|
||||||
@ -197,8 +209,7 @@ pub(crate) const fn default_ttl_extension_policy() -> TtlExtensionPolicy {
|
|||||||
TtlExtensionPolicy::OnStateChanges
|
TtlExtensionPolicy::OnStateChanges
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A fluent builder to construct a [`SessionMiddleware`] instance with custom configuration
|
/// A fluent, customized [`SessionMiddleware`] builder.
|
||||||
/// parameters.
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct SessionMiddlewareBuilder<Store: SessionStore> {
|
pub struct SessionMiddlewareBuilder<Store: SessionStore> {
|
||||||
storage_backend: Store,
|
storage_backend: Store,
|
||||||
@ -236,6 +247,22 @@ impl<Store: SessionStore> SessionMiddlewareBuilder<Store> {
|
|||||||
/// Check out [`SessionLifecycle`]'s documentation for more details on the available options.
|
/// Check out [`SessionLifecycle`]'s documentation for more details on the available options.
|
||||||
///
|
///
|
||||||
/// Default is [`SessionLifecycle::BrowserSession`].
|
/// Default is [`SessionLifecycle::BrowserSession`].
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// use actix_web::cookie::{Key, time::Duration};
|
||||||
|
/// use actix_session::{SessionMiddleware, config::PersistentSession};
|
||||||
|
/// use actix_session::storage::CookieSessionStore;
|
||||||
|
///
|
||||||
|
/// const SECS_IN_WEEK: i64 = 60 * 60 * 24 * 7;
|
||||||
|
///
|
||||||
|
/// // creates a session middleware with a time-to-live (expiry) of 1 week
|
||||||
|
/// SessionMiddleware::builder(CookieSessionStore::default(), Key::from(&[0; 64]))
|
||||||
|
/// .session_lifecycle(
|
||||||
|
/// PersistentSession::default().session_ttl(Duration::seconds(SECS_IN_WEEK))
|
||||||
|
/// )
|
||||||
|
/// .build();
|
||||||
|
/// ```
|
||||||
pub fn session_lifecycle<S: Into<SessionLifecycle>>(mut self, session_lifecycle: S) -> Self {
|
pub fn session_lifecycle<S: Into<SessionLifecycle>>(mut self, session_lifecycle: S) -> Self {
|
||||||
match session_lifecycle.into() {
|
match session_lifecycle.into() {
|
||||||
SessionLifecycle::BrowserSession(BrowserSession {
|
SessionLifecycle::BrowserSession(BrowserSession {
|
||||||
|
@ -35,6 +35,16 @@ use crate::{
|
|||||||
/// [`SessionStore`]);
|
/// [`SessionStore`]);
|
||||||
/// - a secret key, to sign or encrypt the content of client-side session cookie.
|
/// - a secret key, to sign or encrypt the content of client-side session cookie.
|
||||||
///
|
///
|
||||||
|
/// # How did we choose defaults?
|
||||||
|
/// You should not regret adding `actix-session` to your dependencies and going to production using
|
||||||
|
/// the default configuration. That is why, when in doubt, we opt to use the most secure option for
|
||||||
|
/// each configuration parameter.
|
||||||
|
///
|
||||||
|
/// We expose knobs to change the default to suit your needs—i.e., if you know what you are doing,
|
||||||
|
/// we will not stop you. But being a subject-matter expert should not be a requirement to deploy
|
||||||
|
/// reasonably secure implementation of sessions.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use actix_web::{web, App, HttpServer, HttpResponse, Error};
|
/// use actix_web::{web, App, HttpServer, HttpResponse, Error};
|
||||||
/// use actix_session::{Session, SessionMiddleware, storage::RedisActorSessionStore};
|
/// use actix_session::{Session, SessionMiddleware, storage::RedisActorSessionStore};
|
||||||
@ -103,16 +113,6 @@ use crate::{
|
|||||||
/// .await
|
/// .await
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
|
||||||
/// ## How did we choose defaults?
|
|
||||||
///
|
|
||||||
/// You should not regret adding `actix-session` to your dependencies and going to production using
|
|
||||||
/// the default configuration. That is why, when in doubt, we opt to use the most secure option for
|
|
||||||
/// each configuration parameter.
|
|
||||||
///
|
|
||||||
/// We expose knobs to change the default to suit your needs—i.e., if you know what you are doing,
|
|
||||||
/// we will not stop you. But being a subject-matter expert should not be a requirement to deploy
|
|
||||||
/// reasonably secure implementation of sessions.
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SessionMiddleware<Store: SessionStore> {
|
pub struct SessionMiddleware<Store: SessionStore> {
|
||||||
storage_backend: Rc<Store>,
|
storage_backend: Rc<Store>,
|
||||||
@ -125,7 +125,7 @@ impl<Store: SessionStore> SessionMiddleware<Store> {
|
|||||||
///
|
///
|
||||||
/// To create a new instance of [`SessionMiddleware`] you need to provide:
|
/// To create a new instance of [`SessionMiddleware`] you need to provide:
|
||||||
/// - an instance of the session storage backend you wish to use (i.e. an implementation of
|
/// - an instance of the session storage backend you wish to use (i.e. an implementation of
|
||||||
/// [`SessionStore]);
|
/// [`SessionStore`]);
|
||||||
/// - a secret key, to sign or encrypt the content of client-side session cookie.
|
/// - a secret key, to sign or encrypt the content of client-side session cookie.
|
||||||
pub fn new(store: Store, key: Key) -> Self {
|
pub fn new(store: Store, key: Key) -> Self {
|
||||||
Self::builder(store, key).build()
|
Self::builder(store, key).build()
|
||||||
@ -135,7 +135,7 @@ impl<Store: SessionStore> SessionMiddleware<Store> {
|
|||||||
///
|
///
|
||||||
/// It takes as input the two required inputs to create a new instance of [`SessionMiddleware`]:
|
/// It takes as input the two required inputs to create a new instance of [`SessionMiddleware`]:
|
||||||
/// - an instance of the session storage backend you wish to use (i.e. an implementation of
|
/// - an instance of the session storage backend you wish to use (i.e. an implementation of
|
||||||
/// [`SessionStore]);
|
/// [`SessionStore`]);
|
||||||
/// - a secret key, to sign or encrypt the content of client-side session cookie.
|
/// - a secret key, to sign or encrypt the content of client-side session cookie.
|
||||||
pub fn builder(store: Store, key: Key) -> SessionMiddlewareBuilder<Store> {
|
pub fn builder(store: Store, key: Key) -> SessionMiddlewareBuilder<Store> {
|
||||||
SessionMiddlewareBuilder::new(store, config::default_configuration(key))
|
SessionMiddlewareBuilder::new(store, config::default_configuration(key))
|
||||||
|
Loading…
Reference in New Issue
Block a user