DEV Community

Art
Art

Posted on • Originally published at blog.dailysandbox.pro on

Ditch the Passwords: How Magic Links are Simplifying Logins

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

Enter fullscreen mode Exit fullscreen mode
  • 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',
  },
});

Enter fullscreen mode Exit fullscreen mode

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.


1900+ FREE RESOURCES FOR DEVELOPERS!! ❤️ 😍🥳 (updated daily)

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

Visit dailysandbox.pro for free access to a treasure trove of resources!


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!');
});

Enter fullscreen mode Exit fullscreen mode

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');
  }
});

Enter fullscreen mode Exit fullscreen mode

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'));

Enter fullscreen mode Exit fullscreen mode

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!

Top comments (0)