Routes, validation with Pydantic, dependencies, async endpoints and security. Every answer is short enough to say aloud, and every question links to the lesson that teaches it.
54 questionsLast updated
Authentication(continued)
109.How do you test a protected route in FastAPI?
Use TestClient. Either log in through /token and send the returned token in the header, or use app.dependency_overrides to replace the current-user dependency with a fake user. Clear the overrides after the test.
110.Is the OAuth2 password flow still recommended?
It is fine for a login screen of your own first-party app, which is how most course and small projects use it. The OAuth 2.1 draft removes it because third-party apps would see user passwords. For third-party sign-in, use the authorisation code flow with PKCE, usually through a provider.
111.What are the risks of bearer tokens and how do you reduce them?
Anyone who copies a token can act as the user. Use HTTPS only, keep tokens short-lived, never put them in URLs or logs, and allow revoking or rotating them. Store them carefully on the client.
112.Why return the same error for an unknown user and a wrong password?
Different messages let an attacker test which emails or usernames have accounts. One message hides this. Also compare hashes in constant time, and consider a rate limit on the login route.
A JWT is a signed text with three dot-separated parts: a header with the algorithm, the claims such as sub and exp, and a signature. The server signs with a secret key and later verifies the signature, so it does not need to store sessions. The claims are only encoded, so anyone can read them.
No. A normal signed JWT is readable by anyone who holds it. The signature only proves nobody changed it. Never put passwords or private data in it. If you need confidentiality, use an encrypted token format or keep the data on the server.
115.Why do we use both an access token and a refresh token?
A short-lived access token limits damage if it leaks. The refresh token lets the user stay logged in without typing the password every few minutes. The refresh token goes to one route only and can be rotated and revoked.
116.What attacks does the algorithms parameter in jwt.decode prevent?
The header says which algorithm signed the token. If the server trusted it, an attacker could set alg to none or confuse an asymmetric and a symmetric algorithm. Passing a fixed list makes the server decide.
117.How do you log a user out if JWTs are stateless?
Keep access tokens short, and keep a server-side list of valid refresh token ids. Logging out deletes the id, so the user cannot get new access tokens. For immediate revoke of access tokens, keep a small deny list of their ids until they expire.
118.What is refresh token rotation and reuse detection?
Each use of a refresh token returns a new one and invalidates the old one. If an invalidated token arrives again, two parties have it, so the server revokes all tokens of that session and forces a new login.
Keep the access token in memory and the refresh token in an HttpOnly, Secure, SameSite cookie. localStorage is readable by any script on the page, so one XSS bug exposes the tokens. A cookie needs CSRF care; SameSite and a refresh-only route help.
HS256 uses one shared secret, so every service that verifies tokens can also create them. It suits a single backend. RS256 signs with a private key and verifies with a public key, so many services can verify without being able to issue tokens. Use it when several services or third parties verify.
121.Walk me through a secure sign-up and login flow in FastAPI.
Sign-up validates the input, hashes the password with a salted slow hash and stores only the hash. Login finds the user, verifies the hash with a constant-time compare and returns a short-lived access token and a refresh token. Protected routes verify the access token on every request. Wrong user and wrong password give the same error.
122.How would you review a login system for weaknesses?
Check how passwords are stored (salted, slow hash), how secrets and keys are kept (environment, not code), token lifetimes and the type claim, comparison methods, error messages that leak usernames, rate limiting on login, transport over HTTPS and where tokens are stored in the client.
123.An access token expired. What happens next in your design?
The API answers 401. The client sends the refresh token to the refresh route, gets a new access token (and a new refresh token with rotation) and repeats the request. If the refresh token has expired or was reused, the user must log in again.
124.Why verify the type claim as well as the signature?
Both token kinds are signed with the same key, so both have valid signatures. Without a type check, a long-lived refresh token could be used as an access token and the short lifetime would give no protection.
125.Where does the secret key for signing tokens come from, and what if it leaks?
It is read from an environment variable or a secrets manager, never committed to code. If it leaks, anyone can forge tokens, so rotate the key at once, which invalidates existing tokens, and force users to log in again.
126.What is the difference between authentication and authorisation?
Authentication proves who the caller is, for example with a password and a token. Authorisation decides what that caller may do, for each action and each record. Both are needed: a logged-in user is not allowed to do everything.
401 Unauthorized means the request has no valid identity: missing, expired or bad token. It should carry a WWW-Authenticate header. 403 Forbidden means the identity is known but the user lacks permission. Sometimes 404 is used for records the user must not know exist.
Write a dependency that reads the current user and raises 403 when the role is not allowed. A factory such as require_roles('admin') lets routes declare what they need in one line. The check runs before the route body and can be tested and overridden.
129.Roles or permissions: which should code check?
Check permissions, such as orders:refund, and map roles to sets of permissions in one table. Role names change as the business grows, while the actions stay stable. New roles then need only a table change.
Insecure direct object reference, now called broken object-level authorisation, happens when a user changes an id in a request and reaches someone else's record. Prevent it by checking ownership or permission for every record, filtering queries by the current user, and never trusting ids from the client.
132.What does deny by default mean in access control?
Access is refused unless a rule allows it. Unknown roles, missing permissions and new routes are blocked until someone adds a rule. A forgotten rule then causes an error message, not a data leak.
133.Where do you keep the user's role, and can you trust it from the client?
Keep it in the database and, for speed, in a signed token claim. Never trust a role field sent in a request body, header or query. If roles can change often, read them from the database or keep access tokens short so changes take effect quickly.
134.What is CORS and why does the browser need it?
Browsers stop a page from reading replies of another origin, to protect users from hostile sites. CORS lets a server say which other origins may read its replies, using headers such as Access-Control-Allow-Origin. The browser enforces it.
An origin is the combination of scheme, host and port. https://shop.example and https://shop.example:8443 are different origins, and so are http and https. The path is not part of it.
For requests that could change data, such as PUT, DELETE, or ones with Authorization or JSON content type, the browser first sends an OPTIONS request with the origin, method and headers it wants to use. The server answers which are allowed, and the browser caches the answer for max-age seconds. Only then does the real request go out.
Add CORSMiddleware with a fixed list of front-end origins read from settings, only the methods and headers you need, and allow_credentials only when cookies are used. Never copy the request's Origin header into the allow list.
138.Why not use allow_origins=['*'] together with credentials?
Credentials such as cookies are sent with the request. With any origin allowed, any website could make a request in the visitor's browser and read the private reply. Browsers refuse the literal * with credentials, and Starlette echoes the origin instead, which is even riskier. Use an explicit list.
No. It restricts what browsers show to scripts from other sites. Attackers use curl or scripts and ignore it. Protect the API with authentication, authorisation, input validation and rate limits.
140.Your front end gets a CORS error but the server log shows the request succeeded. Why?
The server answered, but the reply lacks the allow-origin header for that origin, so the browser refuses to expose it to the page. Fix the allowed origins in the server settings. Also check that the preflight succeeds, because errors from other middleware can hide the CORS headers.
They are different. CORS controls which sites can read replies. CSRF is when a hostile site makes the browser send a request with the user's cookies, which CORS does not stop for simple requests. Use SameSite cookies, CSRF tokens or bearer tokens in headers to defend.
To stop abuse and overload: password guessing on login, scraping, spam through reset emails, expensive queries and bugs in client code that loop. It also protects fair use among customers and keeps costs predictable.
143.Explain the fixed window algorithm and its weakness.
Time is split into equal slots and each client's requests are counted per slot. When a slot ends, the count resets. It is cheap and easy, but a client can send a full quota at the end of one slot and another at the start of the next, so about double the rate passes around the boundary.
144.How does a token bucket work, and why is it popular?
Each client has a bucket with a capacity that refills at a fixed rate. A request removes a token and is refused if none is left. It allows bursts up to the capacity and a steady average rate, uses little memory and avoids the boundary problem.
145.What is a sliding window and how is it different?
A sliding window counts requests in the last N seconds from now, using a log of timestamps or a weighted blend of two fixed windows. It is fairer than a fixed window but costs more memory or work.
146.What status code and headers should a rate-limited response have?
429 Too Many Requests with a Retry-After header, and often headers that show the limit, the remaining count and the reset time. The body should have a clear message.
147.How do you rate limit across several server instances?
Keep the counters in a shared fast store such as Redis, with atomic operations or a script so two servers cannot both see room for one more request. Many teams also limit at the gateway or reverse proxy before requests reach the app.
The user id or API key for signed-in routes, since it is fair and hard to dodge. The client address for anonymous routes such as login, combined with a limit per username so one account cannot be attacked from many addresses. Read the address from a trusted proxy header.
149.How do you test a rate limiter without waiting?
Inject the clock. The limiter calls a clock function that a test replaces with a fake, and the test advances time by hand. The tests then run instantly and give the same result every time.
150.What is SQL injection and how do you prevent it?
It happens when user input is joined into a SQL string and so becomes part of the command, letting an attacker read or change other data. Prevent it with parameterised queries or an ORM that uses them, allow-lists for table and column names, least-privilege database accounts, and by never showing raw database errors.
Mostly, because it uses bound parameters for values. But raw text queries, string-built filters, text() with an f-string and unchecked sort columns can still be injectable. Review those places.
Cross-site scripting is running attacker-supplied script in a victim's browser. Stored XSS saves the payload, for example in a comment. Reflected XSS puts it in a link. DOM-based XSS happens in browser code that inserts data as HTML. Escape output for the right context, avoid innerHTML, and add a Content-Security-Policy.
153.How do you keep secrets safe in a Python project?
Read them from environment variables or a secrets manager, never commit .env files, add them to .gitignore, use different values for each environment, rotate them, and fail at start-up when one is missing. If a secret was committed, treat it as leaked and rotate it, because Git history keeps it.
154.What is mass assignment and how do you stop it in FastAPI?
It is copying all request fields into a model or row, so a user can set protected fields such as role or is_admin. Use separate Pydantic input and output models that list only the allowed fields, consider extra='forbid', and set sensitive fields in server code.
Insecure direct object reference, also called broken object-level authorisation, is when users can reach other users' records by changing an id. Fix it by checking ownership or permission on every access, ideally inside the query, and by never trusting an id from the client.
156.Why is validating input on the client not enough?
Attackers send requests directly and skip the front end. The server must validate type, length, range and allowed values for every input, and encode output for where it is placed.
157.Name some items from the OWASP Top 10 and a fix for each.
Broken access control: check permissions on every request. Injection: use parameters. Cryptographic failures: use TLS and slow password hashes. Security misconfiguration: safe defaults, no debug in production. Vulnerable components: update and scan dependencies. Logging failures: log security events, not secrets.
158.In what order do you apply rate limit, authentication, authorisation and validation, and why?
Rate limit first, so abusers cost little. Then authentication to identify the caller, authorisation for the role and permission, then the owner check for the record, and validation of the input. An early failure returns early, and each gate reveals as little as possible.
159.How do you secure an endpoint that returns a customer's order?
Require a valid token, take the user id from the token, query with both the order id and the owner id, answer 404 when nothing is found, return only the needed fields through a response model, and add a rate limit. Log access to sensitive data.
160.What would you check in a code review for a FastAPI service?
SQL built from strings, unescaped HTML, keys or passwords in code, request bodies copied into models, missing owner checks, wide CORS with credentials, routes without authentication, missing limits on login, debug mode in production and detailed error messages shown to users.
161.A user changes their role to admin by adding a field in the sign-up request. What went wrong and how do you fix it?
The server copied all request fields into the user record, a mass assignment flaw. Use a Pydantic input model with only email and password, set role on the server, return a separate output model, and consider extra='forbid' to reject unknown fields.
162.How do you protect a login route from password guessing?
Slow password hashing, a rate limit per address and per username, a short lockout or growing delay, the same error message for a wrong user and wrong password, and monitoring for many failures. Add multi-factor sign-in for sensitive accounts.