Interview Insights · Full Stack Developer
The Full Stack Developer Answer That Instantly Builds My Confidence
Quick summary — The login answer
When a candidate explains their own login flow clearly, I stop wondering whether they built the project. Authentication touches every layer of a full stack app: the database, the backend, the browser and security. You cannot explain it well without having built and debugged it. A confident answer covers four points in order: passwords are hashed with a slow algorithm like bcrypt, login compares the hash and returns the same error for any failure, the client keeps a token or session ID in a safe place, and a middleware checks it on every protected request. Add one trade-off and the answer is complete.
In this guide you will learn:
- Why the login question is such a strong signal for full stack roles
- The four-part structure of a confident authentication answer
- Working bcrypt and JWT code for an Express backend
- Where to store tokens in the browser and why it matters
- How to discuss sessions vs JWT as a real trade-off
SECTION 01Why the login question tells me so much
Most full stack projects on fresher resumes have a login page. Many were built by following a tutorial. That is fine as a start, but in the interview I need to know whether you understood what you built. Login is the perfect test, because it forces you to talk about every layer at once.
A candidate who really built it remembers the details: the bcrypt cost factor they used, the bug where the token was not sent with requests, the CORS error when cookies refused to work. A candidate who only copied it describes login as 'we check the email and password in the database'. Within a minute I can usually tell which one I am talking to.
| Part of the answer | Weak version | Strong version | Why it builds confidence |
|---|---|---|---|
| Password storage | We store the password | bcrypt hash with a salt, cost factor set | Shows security basics are understood |
| Login check | Find user where password matches | Find by email, then bcrypt.compare | Shows how hashing actually works |
| After login | We get a token | Signed JWT with user id and expiry | Knows what is inside the token |
| Protected routes | Frontend hides pages | Backend middleware verifies every request | Understands where security really lives |
Q: How does login work in your project?
A: The user enters email and password. We send
it to the backend. The backend checks the database
and if it matches we send a token. The frontend
saves it and shows the dashboard. If not logged in,
the dashboard is hidden.
What I note: no hashing, no idea what the token is,
and 'hidden on the frontend' as security.Q: How does login work in your project?
A: On signup I hash the password with bcrypt,
cost 12, and store only the hash. On login I find
the user by email and run bcrypt.compare. If either
step fails I return the same 'invalid credentials'
message. If it passes, I sign a JWT with the user id
and a 15-minute expiry and send it as an httpOnly
cookie. Every protected API route goes through an
auth middleware that verifies the token first.
The second answer takes under a minute to say. It is not long. It is ordered, and every sentence contains a real decision.
SECTION 02Hashing and checking passwords the right way
The first half of the answer is about passwords. Plain text storage is an immediate red flag. Fast hashes like plain SHA-256 are also not ideal for passwords, because attackers can try enormous numbers of guesses quickly. Password hashing algorithms such as bcrypt, scrypt or Argon2 are deliberately slow and include a random salt, so identical passwords produce different hashes.
The login check has one subtle point that impresses interviewers: return the same error whether the email does not exist or the password is wrong. Different messages let an attacker discover which emails are registered.
| Choice | Problem or benefit | Use it? | What to say in the interview |
|---|---|---|---|
| Plain text password | Anyone with database access sees it | Never | That would expose every user if the DB leaked |
| Plain SHA-256 | Fast, so guessing is cheap | Not for passwords | Fine for checksums, too fast for passwords |
| bcrypt with cost factor | Slow, salted, widely supported | Yes | I set the cost so hashing takes a noticeable fraction of a second |
| Separate error messages | Reveals which emails exist | No | I return one generic invalid-credentials message |
// npm install bcrypt
const bcrypt = require('bcrypt');
router.post('/register', async (req, res, next) => {
try {
const { email, password } = req.body;
if (!email || !password || password.length < 8) {
return res.status(400).json({ error: 'Email and 8+ char password required' });
}
const hash = await bcrypt.hash(password, 12); // salt is generated inside
const user = await User.create({ email: email.toLowerCase(), passwordHash: hash });
res.status(201).json({ id: user.id, email: user.email });
} catch (err) {
if (err.code === 11000) { // MongoDB duplicate key
return res.status(409).json({ error: 'Email already registered' });
}
next(err);
}
});const jwt = require('jsonwebtoken');
router.post('/login', async (req, res, next) => {
try {
const { email, password } = req.body;
const user = await User.findOne({ email: (email || '').toLowerCase() });
const ok = user && await bcrypt.compare(password || '', user.passwordHash);
if (!ok) {
return res.status(401).json({ error: 'Invalid email or password' });
}
const token = jwt.sign({ sub: user.id }, process.env.JWT_SECRET, { expiresIn: '15m' });
res.cookie('token', token, {
httpOnly: true,
secure: true,
sameSite: 'lax',
maxAge: 15 * 60 * 1000
});
res.json({ id: user.id, email: user.email });
} catch (err) {
next(err);
}
});
One honest caveat you can mention: the register route reveals that an email is already registered. Many products accept that for usability. A stricter design sends a 'check your email' message in every case. Raising this yourself shows you see the trade-off.
SECTION 03Tokens, cookies and the sessions vs JWT trade-off
The second half of the answer is about what happens after login. The server needs a way to recognise the user on later requests. There are two common approaches. With server sessions, the server stores session data and the browser holds only a session ID cookie. With JWTs, the server signs a token containing the user id and expiry, and verifies the signature on each request without a lookup.
Where the browser stores the token matters too. localStorage is easy but readable by any JavaScript on the page, so a cross-site scripting bug can steal it. An httpOnly cookie cannot be read by JavaScript, which removes that risk, but cookies are sent automatically, so you also think about CSRF, often handled with the SameSite attribute.
| Aspect | Server session | JWT | Typical choice |
|---|---|---|---|
| Where state lives | Server or Redis store | Inside the signed token | Sessions for classic web apps |
| Logout or revoke | Delete the session, done | Hard before expiry without a blocklist | Short JWT expiry plus refresh token |
| Scaling servers | Needs a shared session store | Any server can verify the signature | JWT for many services or mobile clients |
| Browser storage | httpOnly cookie with ID | httpOnly cookie or memory | Avoid localStorage for long-lived tokens |
// npm install cookie-parser jsonwebtoken
const cookieParser = require('cookie-parser');
app.use(cookieParser());
function requireAuth(req, res, next) {
const token = req.cookies.token;
if (!token) return res.status(401).json({ error: 'Not logged in' });
try {
const payload = jwt.verify(token, process.env.JWT_SECRET);
req.user = { id: payload.sub };
next();
} catch (err) {
return res.status(401).json({ error: 'Session expired' });
}
}
app.get('/api/me', requireAuth, async (req, res) => {
const user = await User.findById(req.user.id).select('email');
res.json(user);
});// The cookie is sent automatically, but only if
// credentials are included on cross-origin requests.
async function loadProfile() {
const res = await fetch('/api/me', { credentials: 'include' });
if (res.status === 401) {
window.location.assign('/login');
return null;
}
if (!res.ok) throw new Error('Could not load profile');
return res.json();
}
// On the Express side, a different-origin frontend
// also needs CORS configured with credentials: true
// and an exact origin, not '*'.
If you used localStorage in your project, do not hide it. Say so, explain the XSS risk, and describe how you would move to an httpOnly cookie. Knowing the weakness of your own choice is exactly what builds confidence.
SECTION 04Build your own login answer
Write your project's login answer before the interview, check every detail against your actual code, then practise saying it. These templates help you cover each layer without rambling.
MY LOGIN ANSWER (under 90 seconds)
1. Storage:
"On signup I hash with ____, cost ____."
2. Login check:
"I find the user by ____ and compare with ____.
On failure I return ____."
3. After login:
"I issue a ____ containing ____,
expiring in ____, stored in ____."
4. Protection:
"Every protected route uses ____ to ____."
5. Trade-off:
"I chose ____ because ____; the cost is ____."OPEN YOUR PROJECT AND CONFIRM
[ ] Where is the password hashed? File: ______
[ ] Which library and cost factor? __________
[ ] What does the login error message say? ___
[ ] Where is the token or session stored? ____
[ ] Where is the JWT secret loaded from? _____
[ ] Which routes use the auth middleware? ____
[ ] What happens when the token expires? _____
[ ] Is the secret or .env file in Git? Y / N
Any surprise here? Fix it or prepare to
explain it honestly.QUESTIONS TO ANSWER ALOUD
- Why not hash passwords with plain SHA-256?
- What is inside your JWT? Can users read it?
- How would you log a user out everywhere?
- Why httpOnly? What does SameSite do?
- What happens if someone steals the token?
- How would you add Google sign-in later?
Note: a JWT payload is only base64url encoded,
not encrypted. Never put secrets in it.
SECTION 05Tips for answers that build trust quickly
The same pattern that makes the login answer strong works for other full stack questions too.
- Answer in the order data flows — Follow the request from browser to server to database and back. Interviewers can follow a flow much more easily than a list of facts.
- Name the exact library — Saying bcrypt, jsonwebtoken or express-session is more convincing than 'some encryption'. It shows you actually installed and used them.
- Mention one bug you hit — A line like 'cookies did not work until I set credentials include' proves hands-on work better than any claim.
- Separate UX from security — Make it clear that hiding UI is convenience and that the server enforces access. This distinction separates juniors who understand from those who copied.
- Own your weak choices — If you stored tokens in localStorage, say so and explain the better option. Honesty plus improvement is a strong combination.
SECTION 06Interview Q&A — The login answer
Q1Why should passwords be hashed instead of encrypted?
Encryption is reversible with a key, so anyone who gets the key can recover every password. Hashing is one-way: the server never needs the original password, only to check that a login attempt produces the same hash. Password hashing algorithms like bcrypt add a salt and are deliberately slow to make guessing expensive.
Q2What is inside a JWT?
Three base64url-encoded parts separated by dots: a header with the algorithm, a payload with claims such as the user id and expiry, and a signature. The payload is readable by anyone who has the token, so it should not contain secrets. The signature lets the server detect any change to the header or payload.
Q3What does the httpOnly cookie flag do?
It stops JavaScript running in the page from reading the cookie through document.cookie. That means an XSS bug cannot simply read and send the token to an attacker. The browser still sends the cookie with matching requests automatically.
Q4How do you log a user out when using JWTs?
On the client, I clear the cookie by sending it back with an expired date. Because the JWT itself stays valid until expiry, I keep access tokens short-lived. For logout everywhere, I store refresh tokens on the server and delete them, or keep a token version on the user record that is checked during verification.
Q5What is the purpose of the SameSite cookie attribute?
It controls whether the browser sends the cookie on requests that come from other sites. Lax, the common default, sends it on top-level navigations but not on most cross-site requests like form posts from another domain, which reduces CSRF risk. Strict never sends it cross-site, and None requires the Secure flag.
SECTION 07Test yourself — The login answer quiz
Five questions. No sign-up.
0 / 5Pick an answer to see why it is right or wrong.
SECTION 08Frequently asked questions
How do I explain authentication in a full stack interview?
Walk through it in order: password hashing on signup, hash comparison on login, the token or session issued after login, where the browser stores it, and the middleware that checks it on protected routes. End with one trade-off you considered.
Is JWT or session-based authentication better?
Neither is always better. Sessions are simple to revoke and suit classic web apps. JWTs are convenient when many services or mobile clients need to verify users without a shared store. Short expiry and refresh tokens are common with JWTs.
Should I store JWT in localStorage or cookies?
An httpOnly, Secure cookie with a suitable SameSite setting is generally safer because JavaScript cannot read it. localStorage is simpler but exposed to XSS. If you used localStorage, explain the risk and how you would change it.
What is bcrypt and why is it used?
bcrypt is a password hashing function that adds a random salt and uses a configurable cost factor to make hashing slow. That makes large-scale guessing much more expensive if a database of hashes ever leaks.
What full stack interview questions are asked about security?
Common ones cover password hashing, JWT versus sessions, cookie flags like httpOnly and SameSite, CORS, SQL injection, XSS and how you protect API routes. Interviewers often ask how your own project handled them.
How can I prepare for Full Stack Developer interview answers with a trainer?
Yes. Uncodemy's Full Stack Development Training Course in Noida (classroom and online) includes live projects, one-to-one mock interviews and resume reviews, so you practise Full Stack Developer interview answers with trainer feedback before the real interview. You can book a free demo class from this page to see how the sessions work.
SECTION 09Related reads
Classroom & online · Noida
Build features you can explain end to end
Our Full Stack Development Training Course takes you through React, Node, databases and authentication in real projects, so you can walk any interviewer through your own code.
Talk to a counsellor for current fees- Auth and security modules
- End-to-end MERN projects
- Code walkthrough practice
- Weekday & weekend batches