pub fn authenticate(
db: Db,
) -> impl Fn(Request, Next) -> Pin<Box<dyn Future<Output = Result<Response, Error>> + Send>> + Send + Sync + Clone + 'staticExpand description
Build the authenticate middleware for this project.
The returned middleware:
- Reads the
rustio_sessioncookie. - Looks up the session in the DB; rejects if missing / expired.
- Looks up the user; rejects if missing / inactive.
- On success, attaches
Identityto the request context.
Failure cases do not short-circuit the request. They simply
leave the context without an Identity; handlers then use
require_auth / require_admin to produce the 401 / 403 as
appropriate. This keeps auth additive and lets non-admin routes
continue serving anonymous requests.
Examples found in repository?
examples/admin_demo.rs (line 34)
22async fn main() -> std::io::Result<()> {
23 let db = Db::memory().await.expect("db connect");
24 auth::ensure_core_tables(&db)
25 .await
26 .expect("create auth tables");
27
28 auth::user::create(&db, "admin@example.com", "admin", "admin")
29 .await
30 .expect("seed admin user");
31
32 seed_demo_data(&db).await;
33
34 let router = with_defaults(Router::new()).wrap(authenticate(db.clone()));
35 // No `.model::<T>()` calls: the new engine uses its own
36 // `AdminUiModel` registry (Users + Orders are wired in by
37 // `Admin::register`). The legacy AdminModel + macro path is
38 // intentionally not exercised here so there is exactly one
39 // admin surface in the demo.
40 let router = Admin::new().register(router, &db);
41
42 let addr: SocketAddr = ([127, 0, 0, 1], 3000).into();
43 eprintln!("admin demo: open http://{addr}/admin and sign in as admin@example.com / admin");
44 Server::bind(addr).serve_router(router).await
45}More examples
examples/homepage.rs (line 84)
50async fn main() -> std::io::Result<()> {
51 let addr: SocketAddr = ([127, 0, 0, 1], 3000).into();
52 let db = Db::memory().await.expect("db connect");
53 auth::ensure_core_tables(&db)
54 .await
55 .expect("create auth tables");
56 auth::user::create(&db, "admin@example.com", "admin", "admin")
57 .await
58 .expect("seed admin user");
59
60 let router = with_defaults(Router::new())
61 .get("/whoami", |req, _params| async move {
62 let id = req
63 .ctx()
64 .get::<RequestId>()
65 .map(|r| r.0.to_string())
66 .unwrap_or_else(|| "unknown".into());
67 Ok::<Response, Error>(text(format!("your request id is req-{id}\n")))
68 })
69 .get("/me", |req, _params| async move {
70 let id = require_auth(req.ctx())?;
71 Ok::<Response, Error>(text(format!("hello {}\n", id.email)))
72 })
73 .get("/admin-only", |req, _params| async move {
74 let id = require_admin(req.ctx())?;
75 Ok::<Response, Error>(text(format!("hello admin {}\n", id.email)))
76 })
77 .get("/crash", |_req, _params| async {
78 Err::<Response, Error>(Error::Internal("simulated failure".into()))
79 })
80 .get("/unauth", |_req, _params| async {
81 Err::<Response, Error>(Error::Unauthorized)
82 })
83 .wrap(request_id)
84 .wrap(authenticate(db))
85 .wrap(logger);
86 Server::bind(addr).serve_router(router).await
87}