Ditch the Passwords: How Magic Links are Simplifying Logins
Tired of dealing with forgotten passwords and reset requests? Imagine a world where logging in is as simple as clicking a link in your inbox—no passwords, no hassle. That’s the beauty of magic links. They’re fast, secure, and make user authentication smoother than ever.
Let's get started.
The Magic Begins: Setting Up Your Dependencies
Before we dive into building, let’s grab the tools we need:
npm install express nodemailer jsonwebtoken bcryptjs
- express: The lightweight framework to power your app.
- nodemailer: Handles sending emails, the key to magic links.
- jsonwebtoken: Ensures your links are secure and one-time-use.
- bcryptjs: Adds an extra layer of security by hashing sensitive data.
Building the Foundation: Your Express Server
Now, let’s bring the magic to life. We’ll create a simple Express server to handle the login process and verify magic links. At its core, the server listens for requests, processes the user's email, and sends a magic link for login.
const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const nodemailer = require('nodemailer');
const app = express();
app.use(express.json());
const users = {}; // Simulate a user database
const transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'your-email@gmail.com',
pass: 'your-password',
},
});
This basic setup gets the ball rolling. The magic begins when a user submits their email. Instead of creating an account with a password, we’ll generate a unique token and send it via email. This token, embedded in a link, serves as a one-time-use “password” that lets users log in.
1391+ Free HTML Templates
266+ Free News Articles
48+ Free AI Prompts
210+ Free Code Libraries
36+ Free Code Snippets & Boilerplates for Node, Nuxt, Vue, and more!
24+ Free Open Source Icon Libraries
Sending the Magic: Generating a Magic Link
The heart of the magic link flow lies in this function. When a user enters their email, we hash the email for added security and store it temporarily. Then, we generate a token and send a magic link to the user’s inbox.
app.post('/send-magic-link', async (req, res) => {
const { email } = req.body;
// Simulate saving user to a database
const hashedEmail = await bcrypt.hash(email, 10);
users[email] = { hashedEmail };
// Create a JWT token with the email
const token = jwt.sign({ email }, 'secret-key', { expiresIn: '15m' });
// Magic link with token
const magicLink = `http://localhost:3000/verify-magic-link?token=${token}`;
// Send email with magic link
await transporter.sendMail({
from: 'your-email@gmail.com',
to: email,
subject: 'Your Magic Link',
text: `Click here to login: ${magicLink}`,
});
res.send('Magic link sent!');
});
Here’s where the real power of magic links shines. The user doesn’t need to remember or manage any passwords. They simply check their inbox, click the link, and they’re in. The email contains a token that expires after 15 minutes, ensuring security and limiting risk.
The Big Moment: Verifying the Magic Link
Once the user clicks the link in their email, we need to verify that the token is valid. This step is crucial for making sure the link hasn’t expired or been tampered with. If everything checks out, we log them in.
app.get('/verify-magic-link', (req, res) => {
const { token } = req.query;
try {
// Verify the JWT token
const decoded = jwt.verify(token, 'secret-key');
const email = decoded.email;
// Check if the email exists in the database
if (!users[email]) {
return res.status(400).send('Invalid magic link');
}
res.send(`Logged in as ${email}`);
} catch (error) {
res.status(400).send('Invalid or expired link');
}
});
Once the token is verified, the user is logged in without ever needing a password. This eliminates the weakest link in most security systems: poor password management.
Putting It All Together: Running the Server
Now, let’s tie it all together by running the server. Once everything is set up, simply start your server and test the flow.
app.listen(3000, () => console.log('Server running on port 3000'));
Why Magic Links?
By ditching passwords in favor of magic links, you create a seamless, secure user experience. Magic links eliminate the frustration of forgotten passwords and add an extra layer of security with token expiration. Plus, they’re easy to implement with just a few key packages in Node.js.
For more tips on web development, check out DailySandbox and sign up for our free newsletter to stay ahead of the curve!