Authentication Guide
Authentication verifies the identity of a user or system before granting access to protected resources. This guide covers common authentication strategies, security best practices, and practical implementation examples.
Authentication Types
Type | Description | Typical Use Cases |
---|---|---|
Passwords | Secret string known only to the user. | Basic web apps, internal tools. |
Multi‑Factor (MFA) | Two or more verification methods. | High‑value accounts, compliance. |
OAuth 2.0 | Delegated access using tokens. | Third‑party integrations, social login. |
OpenID Connect | Identity layer on top of OAuth 2.0. | Single sign‑on (SSO) solutions. |
JWT | Signed JSON tokens for stateless auth. | APIs, microservices. |
Certificate‑Based | Public‑key certificates for authentication. | Enterprise VPN, mTLS. |
Best Practices
- Store passwords using a strong adaptive hash (e.g., Argon2, bcrypt, scrypt).
- Enforce minimum password complexity and length.
- Implement rate limiting and account lockout after failed attempts.
- Prefer token‑based authentication (JWT) for stateless APIs.
- Use HTTPS everywhere to protect credentials in transit.
- Rotate secret keys regularly and store them securely (e.g., Vault).
- Adopt MFA for privileged accounts.
- Validate and sanitize all input to prevent injection attacks.
Implementation Steps
- Choose an authentication strategy based on your threat model.
- Set up a secure user store (database with hashed passwords).
- Integrate a library/framework for handling auth flows (e.g., Passport.js, Spring Security).
- Configure HTTPS and secure cookies (HttpOnly, Secure, SameSite).
- Implement session management or token issuance.
- Add MFA if required.
- Test for common vulnerabilities (OWASP Top 10).
Code Samples
Node.js – Password Hashing with bcrypt
const bcrypt = require('bcrypt');
async function hashPassword(plain) {
const salt = await bcrypt.genSalt(12);
return await bcrypt.hash(plain, salt);
}
async function verifyPassword(plain, hash) {
return await bcrypt.compare(plain, hash);
}
Express – JWT Generation & Verification
const jwt = require('jsonwebtoken');
const secret = process.env.JWT_SECRET;
function signToken(payload) {
return jwt.sign(payload, secret, { expiresIn: '1h' });
}
function verifyToken(token) {
try {
return jwt.verify(token, secret);
} catch (e) {
return null;
}
}
FAQ
Why not store plain text passwords?
Storing plain text exposes user credentials if the database is compromised. Hashing with a strong algorithm makes it computationally infeasible to retrieve the original password.
How secure are JWTs?
JWTs are secure when signed with a strong secret or RSA/ECDSA key, contain minimal sensitive data, and have appropriate expiration times.
When should I use OAuth vs. OpenID Connect?
Use OAuth for authorization (granting access to resources). Use OpenID Connect when you also need authentication (identifying the user).