I’ve been trying to understand authentication properly, and it’s finally starting to click.
Why Authentication Is Confusing
When I first tried to add login functionality to my apps, I was overwhelmed:
- Passwords need to be hashed (what’s bcrypt?)
- Sessions vs tokens (what’s the difference?)
- JWTs (what are these and why do people use them?)
- OAuth (how does “Login with Google” work?)
There are so many concepts and approaches.
What I’m Learning About Passwords
Never store plain text passwords: This seems obvious now, but I didn’t understand why at first.
Use bcrypt for hashing: It’s specifically designed for passwords and includes salting automatically.
const bcrypt = require('bcrypt');
// Hashing a password
const hashedPassword = await bcrypt.hash(password, 10);
// Comparing passwords
const isMatch = await bcrypt.compare(password, hashedPassword);
The number (10) is the “salt rounds” - higher is more secure but slower.
Sessions vs Tokens
I’m learning there are two main approaches:
Sessions:
- Server stores session data
- Client gets a session ID in a cookie
- Server looks up session on each request
Tokens (JWT):
- Server creates a signed token
- Client stores token (usually in localStorage)
- Client sends token with each request
- Server verifies token signature
I’m using JWTs for my current project because they’re stateless and work well with APIs.
Understanding JWTs
A JWT (JSON Web Token) has three parts:
- Header (algorithm and token type)
- Payload (user data)
- Signature (verifies the token hasn’t been tampered with)
const jwt = require('jsonwebtoken');
// Creating a token
const token = jwt.sign(
{ userId: user.id },
process.env.JWT_SECRET,
{ expiresIn: '7d' }
);
// Verifying a token
const decoded = jwt.verify(token, process.env.JWT_SECRET);
The secret key is crucial - if someone gets it, they can create fake tokens.
Building Authentication Flow
Here’s what I’m implementing:
Registration:
- User submits email and password
- Hash the password with bcrypt
- Save user to database
- Create JWT token
- Send token to client
Login:
- User submits email and password
- Find user in database
- Compare password with bcrypt
- If match, create JWT token
- Send token to client
Protected Routes:
- Client sends token in Authorization header
- Server verifies token
- If valid, allow access
- If invalid, return 401 Unauthorized
Middleware for Protection
I’m using middleware to protect routes:
function authenticateToken(req, res, next) {
const token = req.headers['authorization']?.split(' ')[1];
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
return res.status(403).json({ error: 'Invalid token' });
}
}
// Using it
app.get('/api/protected', authenticateToken, (req, res) => {
res.json({ message: 'This is protected', user: req.user });
});
Common Mistakes I’m Making
Storing secrets in code: I learned to use environment variables for JWT secrets and API keys.
Not setting token expiration: Tokens should expire for security.
Weak passwords: I need to add password strength requirements.
Not handling token refresh: Long-lived tokens are a security risk, but I haven’t implemented refresh tokens yet.
What I’m Still Learning
- Refresh tokens (how to handle token expiration gracefully)
- OAuth (integrating “Login with Google/GitHub”)
- Two-factor authentication
- Password reset flows
- Rate limiting (preventing brute force attacks)
Security Considerations
I’m learning that authentication is about more than just checking passwords:
- Use HTTPS in production
- Set secure cookie flags
- Implement rate limiting
- Validate all inputs
- Use CORS properly
- Keep dependencies updated
Resources Helping Me
- JWT.io (for understanding JWTs)
- OWASP guidelines (security best practices)
- Udemy course on Node.js security
- Stack Overflow (for specific problems)
My Advice Right Now
If you’re learning authentication:
Start simple: Basic email/password with JWTs before trying OAuth.
Use libraries: Don’t try to build your own crypto. Use bcrypt and jsonwebtoken.
Test thoroughly: Try to break your own authentication.
Read about security: Understanding common attacks helps you prevent them.
Use environment variables: Never hardcode secrets.
Authentication is complex, but I’m starting to feel confident implementing it. There’s still a lot to learn, but I can now build secure login systems for my projects.