Authentication Flow in MERN
Authentication connects frontend UI with backend identity checks.
It answers:
Who is the current user?
JWT-style flow
- User submits login form in React.
- React sends email/password to Express.
- Express validates input.
- Backend verifies password hash.
- Backend creates token.
- React stores auth state.
- Future API requests include token.
- Express middleware verifies token.
Cookie-style flow
- User logs in.
- Backend creates session or token.
- Backend sets
httpOnlycookie. - Browser sends cookie automatically.
- Backend verifies cookie/session on protected APIs.
Frontend state
React often stores:
- current user,
- loading auth state,
- whether user is logged in,
- role/permissions if needed.
But React state is not security.
Backend must still verify every protected request.
End-to-end example
Login from React:
async function login(email, password) {
const response = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
})
const result = await response.json()
if (!response.ok) {
throw new Error(result.error.message)
}
localStorage.setItem('token', result.data.token)
}
Calling a protected API:
async function loadTodos() {
const token = localStorage.getItem('token')
const response = await fetch('/api/todos', {
headers: {
Authorization: `Bearer ${token}`,
},
})
return response.json()
}
Backend route:
app.get('/api/todos', requireAuth, async (req, res) => {
const todos = await Todo.find({ userId: req.user.id })
res.json({ data: todos })
})
Notice the ownership filter:
{ userId: req.user.id }
That prevents one user from reading another user's todos.
Common mistake
Do not protect only the frontend route.
If /dashboard is hidden in React but /api/admin has no backend auth check, the API is still vulnerable.
Interview answer
In MERN authentication, React collects credentials and sends them to the Express API. The backend verifies the user and returns a token or sets a cookie. React uses auth state for UI, but backend middleware must verify every protected API request. Frontend route protection is for UX; backend protection is for security.