Authentication and AuthorizationLesson 4.4
How to hash passwords and store them securely with bcrypt
bcrypt hashing, salt rounds, bcrypt.hash, bcrypt.compare, why not plain SHA256, timing attacks, password never stored plain, environment variables for secret
Secure Password Hashing with bcrypt
Never store plain-text passwords. bcrypt is an adaptive hashing algorithm that includes a salt (random data) and a cost factor, making brute-force attacks computationally expensive.
npm install bcryptjsHashing on registration
const bcrypt = require('bcryptjs');
app.post('/auth/register', async (req, res, next) => {
try {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ error: 'Email and password required' });
}
const saltRounds = 12; // higher = slower = more secure
const hashedPassword = await bcrypt.hash(password, saltRounds);
const user = { id: Date.now(), email, password: hashedPassword };
users.push(user);
res.status(201).json({ id: user.id, email: user.email });
} catch (err) { next(err); }
});Verifying on login
app.post('/auth/login', async (req, res, next) => {
try {
const { email, password } = req.body;
const user = users.find(u => u.email === email);
if (!user) return res.status(401).json({ error: 'Invalid credentials' });
const match = await bcrypt.compare(password, user.password);
if (!match) return res.status(401).json({ error: 'Invalid credentials' });
const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, { expiresIn: '24h' });
res.json({ token });
} catch (err) { next(err); }
});Use the same generic error message for wrong email AND wrong password — attackers should not be able to enumerate valid emails.
