Skip to main content

SessionLayer

Struct SessionLayer 

Source
pub struct SessionLayer<S> { /* private fields */ }
Expand description

Tower layer that provides signed session cookies and typed crate::session::SessionData.

Add this layer to your Axum router. Handlers receive an super::extractor::AuthSession extractor which wraps the SessionHandle stored in request extensions.

let app = Router::new()
    .route("/login", post(login_handler))
    .layer(SessionLayer::new(store, signing_key));

§Configuration

Cookie attributes and TTL are set via the with_* builder methods:

let layer = SessionLayer::new(store, key)
    .with_ttl(Duration::from_secs(7200))
    .with_secure(false)
    .with_same_site(SameSite::Strict);

Implementations§

Source§

impl<S: SessionStore> SessionLayer<S>

Source

pub fn new(store: S, signing_key: [u8; 32]) -> Self

Create a session layer with the given store and 32-byte HMAC signing key.

Uses SessionConfig::default(): production-safe defaults (24-hour TTL, Secure, HttpOnly, SameSite=Lax).

The signing key derives sub-keys via HKDF for cookie HMAC, fingerprint HMAC, and CSRF; keep it in a secret store and rotate per your key-management policy (a fresh layer is required on rotation since the derived keys are cached).

§Example
use axess_core::{MemorySessionStore, session::SessionLayer};
use std::time::Duration;

// Production: load the master key from a secret store (KMS, Vault, …).
// Below uses a fixed value purely for the construction example.
let signing_key: [u8; 32] = [0u8; 32];
let store = MemorySessionStore::default();

let layer = SessionLayer::new(store, signing_key)
    .with_ttl(Duration::from_secs(3600))
    .with_cookie_name("myapp.sid");

// Attach to your router:
//     let app = axum::Router::new().layer(layer);
Source

pub fn derive_subkey(&self, info: &'static [u8]) -> Zeroizing<[u8; 32]>

Derive a 32-byte sub-key from this layer’s master signing key using a caller-supplied info label. Use this to feed CSRF token signing, push-notification HMAC, or any other HMAC site that would otherwise be tempted to reuse the raw master key. Pick a stable byte-string label per use site (e.g. b"my-app.v1.csrf"); changing the label invalidates every value previously derived under it.

The returned bytes are wrapped in zeroize::Zeroizing so they are wiped on drop: a compromise of any derived sub-key with a known label lets an attacker forge against that path, so the material is held under the same drop discipline as the master key. Deref through * or as_ref() to access the raw [u8; 32].

Source

pub fn with_ttl(self, ttl: Duration) -> Self

Override the session TTL (default: 24 hours).

Override the cookie name (default: "axess.sid").

Source

pub fn with_secure(self, secure: bool) -> Self

Set the Secure flag on the session cookie (default: true).

Set to false only for local HTTP development. In production, cookies without the Secure flag can be intercepted on the network.

Source

pub fn with_same_site(self, same_site: SameSite) -> Self

Set the SameSite policy (default: Lax).

Source

pub fn with_http_only(self, http_only: bool) -> Self

Set the HttpOnly flag on the session cookie (default: true).

Source

pub fn with_max_custom_bytes(self, max: usize) -> Self

Override the maximum size (in bytes) of the JSON-encoded custom-data payload. Default: 64 KiB. Set to 0 to disable the clamp entirely (do this only if you have your own size guarding upstream of the session layer).

When the clamp fires, the offending custom payload is dropped to Value::Null and a tracing::warn! is emitted; the session itself is preserved.

Source

pub fn with_path(self, path: impl Into<Arc<str>>) -> Self

Set the cookie Path attribute (default: "/").

Source

pub fn with_binding(self, binding: impl SessionBinding) -> Self

Enable session-to-client binding for hijacking detection.

When enabled, the library hashes client-specific request properties (determined by the SessionBinding implementation) and stores the hash in the session upon authentication. On every subsequent request the hash is recomputed and compared; a mismatch resets the session to Guest (the cookie may have been stolen by a different client).

use axess::session::UserAgentBinding;

let layer = SessionLayer::new(store, key)
    .with_binding(UserAgentBinding);
Source

pub fn with_metrics(self, metrics: impl AuthnMetrics) -> Self

Attach a metrics hook for session-level observability.

Source

pub fn with_device_resolver<R>(self, resolver: R) -> Self
where R: DeviceResolver,

Available on crate feature device only.

Configure a DeviceResolver to stamp SessionData::device_id on every request before the inner handler runs.

Errors returned by the resolver are logged via tracing::warn! and treated as None; device resolution never fails the request. When unset (the default), device_id stays at whatever the loaded session carried, which for new sessions is None.

See docs/identity/device.md for the full design.

Trait Implementations§

Source§

impl<S: Clone> Clone for SessionLayer<S>

Source§

fn clone(&self) -> SessionLayer<S>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<S, Inner> Layer<Inner> for SessionLayer<S>
where S: SessionStore + Clone,

Source§

type Service = SessionService<S, Inner>

The wrapped service
Source§

fn layer(&self, inner: Inner) -> Self::Service

Wrap the given service with the middleware, returning a new service that has been decorated with the middleware.

Auto Trait Implementations§

§

impl<S> Freeze for SessionLayer<S>
where S: Freeze,

§

impl<S> !RefUnwindSafe for SessionLayer<S>

§

impl<S> Send for SessionLayer<S>
where S: Send,

§

impl<S> Sync for SessionLayer<S>
where S: Sync,

§

impl<S> Unpin for SessionLayer<S>
where S: Unpin,

§

impl<S> UnsafeUnpin for SessionLayer<S>
where S: UnsafeUnpin,

§

impl<S> !UnwindSafe for SessionLayer<S>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> ArchivePointee for T

Source§

type ArchivedMetadata = ()

The archived version of the pointer metadata for this type.
Source§

fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata

Converts some archived metadata to the pointer metadata for itself.
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> LayoutRaw for T

Source§

fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>

Returns the layout of the type.
Source§

impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
where T: SharedNiching<N1, N2>, N1: Niching<T>, N2: Niching<T>,

Source§

unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool

Returns whether the given value has been niched. Read more
Source§

fn resolve_niched(out: Place<NichedOption<T, N1>>)

Writes data to out indicating that a T is niched.
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Pointee for T

Source§

type Metadata = ()

The metadata type for pointers and references to this type.
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more