Authentication and Authorization in Modern Web Apps
Understanding the difference between who you are and what you're allowed to do
Authentication vs. Authorization
These two concepts are often confused but serve very different purposes. Authentication answers "Who are you?" — it verifies the identity of a user. Authorization answers "What can you do?" — it determines what resources and actions an authenticated user can access. A robust application needs both, and they should be implemented as separate concerns.
Getting authentication and authorization right is critical. A flaw in either system can expose sensitive data, allow unauthorized actions, or lock legitimate users out of their accounts.
Authentication Strategies
Modern web applications have several authentication options, each with trade-offs:
- Session-based authentication — The server creates a session after login and stores a session ID in a cookie. Simple, well-understood, and works great for traditional server-rendered applications. The server maintains state, which can be a limitation at scale.
- Token-based authentication (JWT) — After login, the server issues a signed JSON Web Token. The client includes it in subsequent requests. Stateless and works well for APIs and SPAs, but tokens can't be easily revoked and must be stored securely on the client.
- OAuth 2.0 / Social Login — Delegates authentication to a third-party provider (Google, GitHub, etc.). Reduces friction for users and offloads password management, but adds dependency on external services.
For most web applications, session-based authentication is the simplest and most secure choice. Use JWT primarily for API-to-API communication or when you genuinely need stateless authentication.
Password Security
If you handle passwords, handle them correctly. Always hash passwords with bcrypt or Argon2 — never MD5, SHA-1, or plaintext. Enforce minimum password length (at least 8 characters) and check against known breached passwords. Implement account lockout or increasing delays after failed login attempts to prevent brute force attacks.
// Laravel handles this correctly by default
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password), // bcrypt by default
]);
Role-Based Access Control (RBAC)
RBAC is the most common authorization model. Users are assigned roles (admin, editor, user), and roles have permissions (create posts, delete users, view analytics). This indirection makes it easy to manage access — you modify a role's permissions once rather than updating every user individually.
Define your permissions granularly: posts.create, posts.edit, posts.delete, users.manage. Check permissions, not roles, in your application logic. This way, if you need to give editors delete access, you add the permission to the role without changing any code.
Two-Factor Authentication
Two-factor authentication (2FA) adds a critical layer of security by requiring something the user knows (password) and something they have (a phone or security key). Implement TOTP-based 2FA using apps like Google Authenticator or Authy. Always provide recovery codes so users aren't locked out if they lose their device.
For sensitive applications, consider making 2FA mandatory for admin accounts. The small inconvenience is worth the significant security improvement.
Session Security
Secure your sessions properly: use httpOnly cookies (prevents JavaScript access), set the secure flag (cookies only sent over HTTPS), configure appropriate SameSite attributes (prevents CSRF), and regenerate the session ID after login (prevents session fixation). Set reasonable session timeouts based on your application's sensitivity — banking apps should timeout quickly, while a blog admin panel can be more lenient.
Share this post: