Plug-and-play Passwordless Authentication with Magic and Gatsby.js

Morgan Richardson
Jun 16 · 6 min read

If there’s one thing web developers know better than anyone else, it’s this: authentication sucks. Authentication is one of those things that seems simple yet oftentimes ends up being a frustrating, overly-complicated process. Even worse, your production app might be completely dependent on your auth server — if it goes down, you’re in trouble.

This is where Magic comes in. With only a few lines of code, you can integrate Magic into your application to enable passwordless authentication using magic links (similar to Slack and Medium).

✨ Why Magic Links?

In my opinion, passwordless is simply better than the typical username/password authentication. It provides developers with a seamless development experience, users love the idea of not having to keep track of a password, and best of all: it works like magic; passwords disappear and everyone’s lives are just made easier.

Passwordless authentication is secure. Over 59% of people reuse their passwords everywhere, leading to poor passwords accounting for 81% of all security breaches [source]. (Gentle reminder to update your passwords! I recommend rotating them every few months.)

Magic leverages blockchain-based, standardized pubic-key cryptography to achieve identity management. When a new user signs up via your Magic integration, a public-private key pair is automatically generated for them.

In order to authenticate requests, a user’s private keys are used to sign cryptographic proofs to verify their identity. Thus, your resource server will no longer need to store and manage (1) hashed + salted passwords or (2) user sessions in its database table.

To learn more about Magic’s enterprise-grade security thanks to the cutting-edge identity tech they use involving zero-knowledge proofs, delegated key management and decentralized ID tokens, visit their security page or read Magic’s Whitepaper.

💻 An Enhanced Developer Experience

Magic is a developer SDK that you can integrate into any application to enable blazing-fast, hardware-secured passwordless authentication with just a few lines of code (even if you already have an existing auth solution). The Magic SDK currently offers support for 32+ ecosystems — from Social Logins like Google, Facebook, and Github to Blockchains like Ethereum, Polkadot, and Solana.

Here’s how it works:

When a user wants to sign up or log in to your application:

  1. User requests a magic link sent to their email address
  2. User clicks on that magic link
  3. User is securely logged into the application

In this tutorial, we’ll demonstrate just how easy it is to get started integrating with Magic in just a few lines of code.

👩🏻‍💻 Integrating Magic with Gatsby.js

Gatsby.js is a React-based static site generator powered by GraphQL. Gatsby essentially takes the best parts of React, Webpack, GraphQL, and various front-end tools to provide a seamless developer experience. If you’re new to Gatsby, you can learn more from their documentation here.

I’m personally a huge fan of Gatsby and have built dozens websites with it. It’s great for building portfolio sites or blogs, both of which you can easily integrate with Magic — which I’ll demonstrate below.

🛠 What We’ll Build

Login screen

In this tutorial we’ll be integrating Magic to a static Gatsby.js site and deploying it to Netlify. Feel free to view and try out the production application live on Netlify here.

Step 1: Clone the Starter Template & Install Dependencies

To get started, clone the starter template from Github here. We’ll be working out of the dev/ directory, but feel free to play around with the final code in the prod/ directory. I recommend following along with the tutorial before jumping into the production code.

To clone the starter template, run the following command from your terminal:
git clone https://github.com/morganrmarie/passwordless-authentication-tutorial.git

Change to the tutorial’s directory:
cd passwordless-authentication-tutorial

And install the project’s dependencies from the root directory:
cd dev && npm install
cd prod && npm install

If you’d like to try the final application, you can run the production application locally from the root folder:
npm run start:prod

Otherwise, to follow along with the tutorial, spin up the development server (also from the root folder):
npm run start:dev

Step 2: Initialize Magic

Before we get started integrating Magic into our application, I recommend you take a look at Magic’s documentation. They’ve got easy-to-follow documentation and helpful guides on other most commonly used developer tools.

The starter template for this tutorial lies in the dev/ directory of this tutorial's codebase. To begin integrating Magic, we'll need to install the Magic Client SDK in the dev/ directory:
npm install --save magic-sdk

By default Gatsby supports two environments: development and production. To support both environments, we’ll create two files in the root of the dev/ and prod/ directories: .env.development and .env.production. Copy the contents (it's only one variable) of .env.example to both files.

Before we initialize Magic, you’ll need to sign up to the Magic Dashboard to get your own API keys. Replace GATSBY_MAGIC_PUBLISHABLE_API_KEY in .env.development and .env.production (in both directories) with your "Publishable API Key" from the Magic Dashboard:

Now that we’ve set our environment variable, we can create an SDK instance to initialize Magic.

Because Gatsby generates static HTML at build time when you run gatsby build, we need to ensure the global window object is defined before importing Magic.

We’ll initialize Magic in the src/lib/magic.js file like so:

import { Magic } from "magic-sdk"let magicif (typeof window !== `undefined`) {   
magic = new Magic(process.env.GATSBY_MAGIC_PUBLISHABLE_API_KEY)
}
export { magic }

Step 3: Handle Authentication

Navigate to the index.js file in src/pages and import your newly-created Magic instance.

import { magic } from "../lib/magic"

Next, we’ll implement our login & logout methods. Handling user sessions is made incredibly easy with Magic. Add these two methods to the same index.js file.

// Handle login with email
const handleEmailLogin = async (e) => {
// Get the current value from the input field
const email = userEmail.current.value
if (!email) return

try {
// Login with Magic ✨
await magic.auth.loginWithMagicLink({
email
})

// Set user metadata
let userMetadata = await magic.user.getMetadata()
setUser(userMetadata)
} catch (error) {
console.error(error)
}
}

// Handle logout
const handleLogout = async () => {
// Logout with Magic
await magic.user.logout()
setUser(null)
}

In our useEffect hook, we'll check if the user is logged in and set their metadata if they are. If not, we'll set the user to null.

useEffect(() => {
// Check if user is logged in
magic.user.isLoggedIn().then((isLoggedIn) => {
return isLoggedIn
// If user is logged in, set metadata
? magic.user.getMetadata().then((userData) => setUser(userData))
: setUser(null)
})
}, [])

Step 4: Deploy

Deploying the application is completely optional, but I’m personally a big fan of Netlify and once you register and connect your Netlify account to your Github, you can configure auto-deployments from the branch of your choice. If you choose to do this, set your build command as gatsby build and the public directory to public.

Don’t forget to set the GATSBY_MAGIC_PUBLISHABLE_API_KEY environment variable in Netlify with your publishable API key from the Magic Dashboard.

🚀 Wrapping Up

So… ready to integrate with Magic? Magic is currently offering users the ability to earn free logins by referring friends. For every friend that signs up for Magic, you’ll both get 3,000 bonus logins — up to 90,000 total.

You saw how easy it was to plug passwordless auth to our Gatsby app with Magic and start playing with the rest of our app’s business logic, so grab your referral link and start sharing!

Follow Magic on Twitter and Instagram to stay up-to-date. Try Magic for free here. ✨

Magic

Plug and play auth that grows with you✨