Skip to main content

SessionStore

Trait SessionStore 

Source
pub trait SessionStore:
    Send
    + Sync
    + 'static {
    // Required methods
    fn load<'life0, 'life1, 'async_trait>(
        &'life0 self,
        raw: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Option<BTreeMap<String, String>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn store<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        data: &'life1 BTreeMap<String, String>,
        previous: Option<&'life2 str>,
    ) -> Pin<Box<dyn Future<Output = Result<Option<String>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;

    // Provided method
    fn with_session_max_age(&self, _secs: i64) -> Option<Box<dyn SessionStore>> { ... }
}
Expand description

Where session contents live between requests.

Both operations are async because a store backed by server state has to talk to it. A client-side store such as CookieStore never awaits anything and simply returns.

Required Methods§

Source

fn load<'life0, 'life1, 'async_trait>( &'life0 self, raw: &'life1 str, ) -> Pin<Box<dyn Future<Output = Option<BTreeMap<String, String>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Recover a session from the cookie value, if it is intact.

Source

fn store<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, data: &'life1 BTreeMap<String, String>, previous: Option<&'life2 str>, ) -> Pin<Box<dyn Future<Output = Result<Option<String>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Persist the session and return the new cookie value, or Ok(None) to leave the visitor’s cookie untouched.

previous is the cookie value this request arrived with, if any. A server-side store needs it to delete the record it is replacing: without it, logging out would leave the old record readable until its own TTV elapsed, which is exactly the revocation a server-side store exists to provide. A client-side store ignores it.

§Errors

Return an Err when something the caller is entitled to assume happened did not, and the case that matters is a withdrawal: an emptied data is a logout, and a logout that never reached the backing store is not a logout. The middleware then answers with that error instead of the handler’s response, because a 200 and a farewell page, sent while the cookie the visitor just asked to be rid of still authenticates, is worse than an honest failure they can retry.

Failing to save is a different question and is usually better swallowed with Ok: the visitor signs in again, which beats a 500 on every route while the backing store is unwell. Which failures are worth a response is therefore the store’s judgement, not a blanket rule.

Provided Methods§

Source

fn with_session_max_age(&self, _secs: i64) -> Option<Box<dyn SessionStore>>

Adopt the session lifetime configured on Sessions::max_age.

Returning a new boxed store opts in; the default returns None, which means “I manage my own expiry” — the right answer for a store backed by server state, which can simply delete the record.

This exists because Max-Age on a cookie is only a hint to a well-behaved client. A store that keeps its state client-side has to enforce the deadline itself, and it can only do that if it is told what the deadline is.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§