Objecitive Question
MCQ
Objecitive Question
NOTE:Please read blog before see objective and mcq
build-secure-session-based-authentication-protected-routes-in-actix-web-rust-production-ready-
Step 1: Why Session-Based Auth in Actix-Web
Session auth is useful when you want the backend to remember the logged-in user without sending JWT on every request. After login, you store user_id, username, and role in session, and later protected routes check these values. This is clean for admin panels and vendor dashboards.
Step 2: Required Dependencies
To use sessions, you must add actix-session and choose a store (cookie store in your case). You also need dotenvy to load environment values and a secure SESSION_KEY to sign cookies.
Step 3: .env Setup
Your .env must include a strong session key and DB URL. In production, SESSION_KEY should be long and random so cookies cannot be forged. Your bind address decides where the server runs.
Step 4: Enable Session Middleware in main.rs
This step is mandatory because without middleware the Session object will not work. You are already using:
SessionMiddleware
CookieSessionStore
Key::derive_from(SESSION_KEY)
This enables storing and reading session values in any handler.
Step 5: Add Login Route (Where login() is called)
In main.rs, the login route connects the URL to your handler function. Because you are using web::scope("/api"), your final endpoint becomes /api/login. This is where frontend hits and session gets stored.
Step 6: Full Login Handler (Store DB data in session)
File: src/handlers/auth.rs
This is the exact place where those session.insert() lines come from. When username/password matches, you store:
username
user_id
role
Now backend “remembers” the user across requests.
Step 7: Add Common Guard Helpers
File: src/handlers/common.rs
Create ensure_login_user_id() so every handler can check session login in one line. This avoids writing repeated session reading logic in each file.
Step 8: Protect Handlers (Example: Shops)
In protected handlers, call:
let user_id = ensure_login_user_id(&session)?;
If user is not logged in, it returns 401 automatically. This is the easiest protection style without writing custom middleware.
Step 9: Logout (Clear session)
Logout should destroy session using session.purge(). This clears cookies and user is treated as guest again.
Step 10: Common Fix: Frontend URL vs Scope
If backend route is under web::scope("/api"), frontend must call /api/.... If frontend calls /home/vehicles but backend route is /api/home/vehicles, you’ll get 404.
Step 1: What is Session-Based Authentication?
Session-based authentication means the server remembers a logged-in user using cookies. After login, user data like user_id, username, and role is stored inside session. Every protected route checks this session to allow or deny access.
Step 2: Required Middleware Configuration (Very Important)
To store DB data in session, you must enable SessionMiddleware in main.rs. Without middleware, Session will not work.
.wrap(
SessionMiddleware::builder(CookieSessionStore::default(), key.clone())
.cookie_secure(false)
.cookie_same_site(SameSite::Lax)
.build(),
)
Why this is required?
Because middleware attaches session handling logic to every incoming request.
Step 3: Why cookie_secure is used?
.cookie_secure(true)
It allows cookies only over HTTPS.
Prevents session hijacking.
Should always be true in production.
Step 4: Why cookie_same_site is used?
.cookie_same_site(SameSite::Lax)
Protects against CSRF attacks.
Controls cross-site cookie sending.
Lax allows normal navigation but blocks risky cross-site requests.
Step 5: Why wrap() is used?
wrap() attaches middleware to your app.
Example:
.wrap(cors)
.wrap(SessionMiddleware::builder(...))
Use it when:
You want authentication middleware
You want CORS handling
You want logging middleware
Step 6: Why CORS is used?
CORS allows frontend (React/Vite) to talk to backend.
let cors = Cors::default()
.allowed_origin("http://localhost:5173")
.supports_credentials();
Use .supports_credentials() if you use sessions, otherwise cookies won’t be sent.
Step 7: Why and When Use web::scope("/api")?
Scope groups related routes under one prefix.
web::scope("/api")
Means:
/login becomes /api/login
/shops becomes /api/shops
Use scope:
To organize routes
To version APIs (/api/v1)
To group protected routes
Step 8: Syntax to Send Route to Handler
.route("/login", web::post().to(handlers::login))
General format:
.route("URL", web::METHOD().to(handler_function))
Step 9: Insert DB Fields into Session
Inside login handler:
session.insert("username", user.username.clone())?;
session.insert("user_id", user.id)?;
session.insert("role", user.role.clone())?;
This stores DB fields inside session.
Step 10: Why Use super Keyword?
use super::common::ApiResponse;
Used when importing from parent module.
Cleaner when files are inside same folder.
Use super when accessing sibling files.
Step 11: Why Use crate Keyword?
use crate::models::{LoginForm, UserRole};
use crate::db::{find_user_by_username, AppState};
Refers to project root.
Used to import modules globally.
Use crate when accessing modules from project root.
Step 12: Why Use actix_web Imports?
use actix_web::{error, web, HttpResponse, Result};
web → route helpers
HttpResponse → send JSON response
Result → handler return type
error → return proper HTTP errors
Step 13: Why Use Macro #[derive(Serialize)]?
#[derive(Serialize)]
Automatically converts struct to JSON.
Required when returning JSON API responses.
Without this, JSON response will fail.
Step 14: Why Use session.purge() on Logout?
session.purge();
Clears entire session.
Removes cookie.
Prevents unauthorized reuse.
Step 15: What Are Authentication Helper Functions?
Reusable guard helpers avoid repeated code.
Example:
pub fn ensure_login_user_id(session: &Session) -> Result<i64> {
session.get::<i64>("user_id")?
.ok_or_else(|| error::ErrorUnauthorized("Login required"))
}
Used to protect routes easily.
Step 16: Meaning of session.get::("user_id")
Reads session value
<i64> tells Rust the expected type
Returns Option<i64>
Step 17: Syntax to Protect Route Using Session
let user_id = ensure_login_user_id(&session)?;
MCQs (with Answers)
To store DB data in session, what configuration is required?
A. Only route configuration
B. Only CORS configuration
C. SessionMiddleware configuration
D. Static files configuration
✅ Answer: C
2) Where do you normally store user_id after successful login?
A. In config.rs
B. In session.insert("user_id", ...)
C. In Cargo.toml
D. In AppState only
✅ Answer: B
3) In your code, why is SESSION_KEY resized to 32 bytes minimum?
A. Because DB requires it
B. Because Key::derive_from expects enough bytes for signing
C. Because Actix requires 8 bytes only
D. Because CORS needs it
✅ Answer: B
4) What is the final API path if you use web::scope("/api") and route "/login"?
A. /login
B. /api/login
C. /auth/login
D. /api/auth/login
✅ Answer: B
5) Which function removes the session completely?
A. session.remove()
B. session.destroy()
C. session.purge()
D. session.clear_cache()
✅ Answer: C
6) Which is the correct way to read user_id from session?
A. session.read("user_id")
B. session.get::("user_id")
C. session.fetch("user_id")
D. session.load("user_id")
✅ Answer: B
7) What will happen if a protected handler calls ensure_login_user_id() and user is not logged in?
A. It returns 500
B. It returns 404
C. It returns 401 Unauthorized
D. It returns 200 empty
✅ Answer: C
8) Which middleware gives access to Session in handlers?
A. Files::new()
B. Cors::default()
C. SessionMiddleware
D. HttpServer
✅ Answer: C
9) Why do we use supports_credentials() in CORS?
A. To allow JavaScript alerts
B. To allow cookies/session to be sent in requests
C. To speed up DB queries
D. To enable static uploads
✅ Answer: B
10) Which session fields are best to store after login in your case?
A. password only
B. username, user_id, role
C. full user table row
D. DB connection string
✅ Answer: B
11) Where should login handler live based on your structure?
A. src/db/auth.rs
B. src/layout.rs
C. src/handlers/auth.rs
D. src/templates/auth.html
✅ Answer: C
12) What does CookieSessionStore mean?
A. Session stored in MySQL
B. Session stored in Redis
C. Session stored inside cookie (signed/encrypted)
D. Session stored in file system
✅ Answer: C
13) If frontend calls request("/home/vehicles") but backend route is /api/home/vehicles, what happens?
A. It works
B. It becomes /api/api/home/vehicles
C. 404 Not Found
D. 401 Unauthorized
✅ Answer: C
14) Why do we keep helpers like ensure_login_user_id() in common.rs?
A. To increase build size
B. To avoid repeated session-check code in every handler
C. To store DB schema
D. To run migrations
✅ Answer: B
15) Which error type should be used for wrong password?
A. ErrorBadRequest
B. ErrorUnauthorized
C. ErrorNotFound
D. ErrorConflict
✅ Answer: B
16) What does .cookie_same_site(SameSite::Lax) help with?
A. DB joins
B. API caching
C. Cookie security against CSRF in common cases
D. File upload size
✅ Answer: C
17) Why should .cookie_secure(true) be used in production?
A. It makes server faster
B. It allows cookie only over HTTPS
C. It stores cookie in DB
D. It enables CORS
✅ Answer: B
18) Which layer should contain SQL queries?
A. handlers/
B. db/
C. templates/
D. main.rs
✅ Answer: B
19) What is the main job of main.rs in Actix-Web?
A. Store HTML templates
B. Start server + configure middleware + register routes
C. Write SQL schema
D. Build frontend
✅ Answer: B
20) Which is the best way to protect a handler quickly?
A. Remove the route
B. Put password in query string
C. Check session with ensure_login_user_id()
D. Use SELECT *
✅ Answer: C
Why use cookie_secure(true)?
A. Faster DB
B. Only allow HTTPS cookies
C. Enable CORS
D. Debug mode
✅ Answer: B
3) cookie_same_site protects against:
A. SQL injection
B. CSRF
C. XSS only
D. Routing error
✅ Answer: B
4) .wrap() is used to:
A. Start server
B. Add middleware
C. Connect DB
D. Compile code
✅ Answer: B
5) Why CORS is used?
A. Allow cross-origin requests
B. Store DB
C. Format JSON
D. Encrypt data
✅ Answer: A
6) web::scope("/api") does:
A. Encrypt route
B. Add route prefix
C. Delete route
D. Store session
✅ Answer: B
7) Syntax to route handler:
A. .handle()
B. .to(handler)
C. .route("/url", web::get().to(handler))
D. .map(handler)
✅ Answer: C
8) Insert session syntax:
A. session.add()
B. session.insert("key", value)
C. session.store()
D. session.set_cookie()
✅ Answer: B
9) super is used for:
A. Root access
B. Parent module access
C. DB join
D. API routing
✅ Answer: B
10) crate is used for:
A. Parent folder
B. Root project reference
C. External DB
D. HTTP response
✅ Answer: B
11) #[derive(Serialize)] is for:
A. DB connection
B. JSON conversion
C. Session insert
D. Routing
✅ Answer: B
12) session.purge():
A. Deletes DB
B. Clears session
C. Encrypts cookie
D. Updates user
✅ Answer: B
13) Guard helper returns:
A. Option
B. Result
C. String
D. Vector
✅ Answer: B
14) session.get::():
A. Reads typed session value
B. Deletes session
C. Creates DB
D. Builds route
✅ Answer: A
15) Unauthorized user should return:
A. 404
B. 200
C. 401
D. 500
✅ Answer: C
16) Session key is used for:
A. CORS
B. Cookie signing
C. SQL
D. Upload
✅ Answer: B
17) Protected route syntax:
A. ensure_login_user_id(&session)?
B. session.insert()
C. session.clear()
D. web::scope()
✅ Answer: A
18) supports_credentials():
A. Allows cookies
B. Blocks cookies
C. Encrypts session
D. Adds DB index
✅ Answer: A
19) Scope helps:
A. Group routes
B. Delete route
C. Hide session
D. Compress image
✅ Answer: A
20) Best place for login handler:
A. db.rs
B. models.rs
C. handlers/auth.rs
D. main.rs
✅ Answer: C
Top comments (0)