pub trait Authenticatable:
Send
+ Sync
+ Sized
+ 'static {
const GUARD: &'static str = "web";
// Required methods
fn auth_id(&self) -> i64;
fn find_for_auth(
id: i64,
) -> impl Future<Output = Result<Option<Self>, AppError>> + Send;
}Expand description
Implemented by an app’s User model (or whatever it calls its
authenticatable type) so larust_support::auth’s guard functions and
the crate::Auth extractor can look a user up from the id stored in
the session.
find_for_auth‘s signature deliberately matches what #[derive(Model)]
already generates (Self::find(id: i64) -> Result<Option<Self>, AppError> - see larust-macros’ model.rs), so a typical impl is a
two-line delegation:
impl larust_support::auth::Authenticatable for User {
fn auth_id(&self) -> i64 { self.id }
async fn find_for_auth(id: i64) -> Result<Option<Self>, AppError> {
Self::find(id).await
}
}Declared as -> impl Future<...> + Send rather than a plain async fn -
native async-fn-in-traits doesn’t propagate auto-trait bounds on the
returned future by default, and the crate::Auth extractor’s
FromRequestParts impl (itself required to return a Send future by
axum-core’s own #[async_trait] declaration - see GOTCHAS.md) calls
this through an async block that needs to stay Send. This doesn’t
change how an implementation looks: implementing this method with a
plain async fn find_for_auth(id: i64) -> Result<Option<Self>, AppError> { Self::find(id).await } still works, since async fn’s desugared
return type already satisfies -> impl Future<...> - only the trait’s
own declaration needs the explicit spelling.
The two-line delegation above is the easy path for a #[derive(Model)]
(SQL-family) app, but it isn’t the only path - this trait has zero
dependency on #[derive(Model)], larust-orm, or SQL of any kind, so a
user model backed by something else entirely (a document store like
Firestore, an in-memory cache, a call to another service) implements it
exactly the same way, just with a different lookup body:
impl larust_support::auth::Authenticatable for User {
fn auth_id(&self) -> i64 { self.id }
async fn find_for_auth(id: i64) -> Result<Option<Self>, AppError> {
// No `#[derive(Model)]` involved - e.g. a hand-written lookup
// against a `larust_support::repository::Repository` impl, or
// any other store this type knows how to query:
MY_USER_REPOSITORY.find(id).await
}
}Provided Associated Constants§
Sourceconst GUARD: &'static str = "web"
const GUARD: &'static str = "web"
This type’s guard name (Laravel’s guard('admin')) - each distinct
name gets its own session slot, so two Authenticatable types (say,
User and Admin) can be logged in independently in the same
browser session rather than overwriting each other’s login state.
Defaults to "web", matching Laravel’s own default guard name, so a
single-guard app never has to think about this - and upgrading an
existing single-guard app to a version of this framework with
multi-guard support doesn’t invalidate already-logged-in sessions
(see larust_auth::guard’s own doc comment for why "web" is
special-cased to the original session key).
A second Authenticatable type that forgets to override this
collides with the first on the same "web" session slot - there’s
no compile-time guard against that (a marker trait can’t know how
many other types implement itself), so name every guard beyond the
first explicitly.
Required Methods§
Sourcefn auth_id(&self) -> i64
fn auth_id(&self) -> i64
The value stored in the session and used to look the user back up on a later request - typically the primary key.
Sourcefn find_for_auth(
id: i64,
) -> impl Future<Output = Result<Option<Self>, AppError>> + Send
fn find_for_auth( id: i64, ) -> impl Future<Output = Result<Option<Self>, AppError>> + Send
Looks up a user by the id Authenticatable::auth_id returned at
login time. Returns Ok(None) (not an error) if the id no longer
resolves to a real user - e.g. the account was deleted after login.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".