Securing your app starts with robust authentication. In this guide, we’ll explore how to implement secure authentication in applications using techniques like HTTP-only cookies, JWT tokens, and MFA. Read on to learn how to fortify your app!
What is authentication?
Authentication is the process of verifying the identity of a user or a system that needs access to specific resources or services. This involves validating credentials like passwords, PINs, fingerprints, or tokens. In IT systems, authentication is a critical step in security, preventing unauthorized access.
Today, many systems rely on multi-factor authentication (MFA), which combines:
- Something you know: Passwords or PINs
- Something you have: Security tokens or mobile apps
- Individual characteristics: Biometrics like fingerprints or facial recognition
This layered approach enhances security and significantly reduces the risk of privacy breaches.
How to create custom authentication with HTTP cookies and JWT tokens
Before we jump to the example we need to know a little bit about HTTP-only Cookie and what is a JWT token.
HTTP-only cookie
HTTP-only cookies are a type of browser cookie that cannot be accessed through JavaScript, making them more secure. It protects against Cross-site Scripting (XSS) attacks.
Here’s how it works:
- When the server sends a response to the browser Cookies are included in the HTTP header.
- The browser automatically stores the cookie and includes it in subsequent requests to the same server.
- Because it is marked as httpOnly JavaScript in the browser, it cannot be accessed or edited. Thus reducing vulnerabilities for client-side JavaScript injection.
JWT
JWT (JSON Web Token) is a compact and comprehensive way to express user identity. It has three parts:
- Title: Contains algorithm and token type.
- Payload: Contains user information such as user IDs, roles, or permissions (but not sensitive information such as passwords).
- Signature: Make sure the token has not been tampered with. It is created by hashing the header and payload with a secret key.
A typical JWT looks like this:
HeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMywicm9sZSI6InVzZ XIiLCJleHAiOjE2MzQ2NzU2MDB9.VnBRuGFbDjEljI4rjQfRjtHCB4Fk5NFOQSc5sWfSzjQ
Here’s how it works:
- The server creates a JWT upon successful login and sends it to the client.
- The client stores the token. (e.g. only in HTTP cookies) and returned with each request.
- The server verifies the token using the secret key.
- If the token is valid The request will be processed. Otherwise, it will be rejected.
We obtained the knowledge needed for a simple custom example here in a few simple steps.
Steps to implement secure authentication in applications
1. User login
Create a login endpoint. When the user logs in with valid credentials, generate a JWT. It may look like this:
const jwt = require('jsonwebtoken');
const token = jwt.sign({ userId: user.id }, 'your_secret_key', { expiresIn: '1h' });
2. Set the HTTP-only cookie
Send the token to the client securely:
res.cookie('authToken', token, { httpOnly: true, secure: true, sameSite: 'strict' });
3. Protect API routes
Create middleware to validate the cookie. Extract the token and verify it:
const token = req.cookies.authToken;
if (!token) return res.status(401).send('Unauthorized');
try {
const user = jwt.verify(token, 'your_secret_key');
req.user = user; // Add user info to request
} catch (err) {
res.status(403).send('Invalid Token');
}
4. Logout
Clear the cookie to log out:
res.clearCookie('authToken');
This is the simplest way to keep your user session secured. Of course, there are a lot of packages that will help you stay authenticated. For more complex setups, consider using tools like Firebase, Supabase, or specialized libraries. So before implementing authentication, one has to be sure about options for different packages that will benefit them.
Making secure authentication in applications more robust
Sometimes simple authentication may not be enough, maybe your application has important information about users or even more sensitive information like a credit card number. If that is the case there are some things one can implement to put your security in another league.
Multi-Factor Authentication (MFA)
MFA combines multiple types of credentials, enhancing security without placing too much reliance on a single factor. For example:
- Something you know: passwords or PINs
- Something you have: mobile apps like Google Authenticator
- Something you are: fingerprints or facial recognition
Developers can integrate MFA using tools like Authy or OS-specific APIs to align with the latest trends in secure login.
Make passwords smarter
While passwordless authentication is gaining traction, passwords remain widely used. Implementation of those practices can strengthen the passwords of users and keep them harder to break through:
- Use libraries like zxcvbn to evaluate password strength dynamically (it is free and works well).
- Integrate APIs like “Have I Been Pwned” to prevent users from selecting compromised passwords.
- Simplify strong password creation with clear prompts and compatibility with password managers.
Secure password storage
Always hash passwords before storage. Algorithms like bcrypt or Argon2 are ideal because they incorporate salting and adaptive functionalities to resist brute-force attacks. Popular libraries in various languages make implementation straightforward. It is a very simple thing to implement too so definitively take this quick win.
Keep everything encrypted
Encryption should be used during transmission and at rest to maintain information security. Strong TLS encryption ensures confidentiality and authentication in secure client-server communication. The latest version of HTTP Hard Transport Security (HSTS) uses TLS encryption to protect data in transit.
Conclusion
Authentication is just one piece of the puzzle in securing your application. To stay secure:
- Keep your knowledge up to date.
- Regularly review your security protocols.
- Keep everything encrypted
- Set password requirements
- Implement multi-factor authentication
By implementing these best practices, you’ll not only protect your users but also build trust and reliability in your application. Unfortunately, we as an online dev community have to do our part in an arms race between us and people who want to steal your credit card data. Keeping up to date with changes is of utmost importance in this field. So, be careful and check our blog for security updates in the future.