HomeBlog#BLM|Subscribe
Checkout my Next.js Course: Bulletproof Next
Published on 22 May, 2020

Simple Auth Setup for Your React App

I recently got super excited about Deeplearning, and wanted to share my experience. So, I created Deeplearning Mantra. I needed to add login functionality to it, but existing solutions are not that simple and hard to manage.
This app is just a side project. I have limited time to spend on it.
Then I found Magic Link. It's simple and easy to use. Here's how it works:
  • User enter the email and waiting for the login to complete
  • They receive an email with a link.
  • User clicks on it
  • Boom, user enter to the app

Try this example app:
Click this image to visit https://nextjs-magic-bank.now.sh
Like to watch instead of reading? Then, watch this:
Play Now

Integrating with Your React App

Magic Link API is simple to use. But, I made it super simple with this React Hook: use-magic-link. Here's how to use it:
Before we do that, create an account on Magic Link and get the "Publishable Key".
Let's say; you want login/logout functionality, here's how to do it:
// Get this with "yarn add use-magic-link"
import useMagicLink from 'use-magic-link'

export default function Home() {
  // create the hook
  const auth = useMagicLink('<Publishable Key>');

  function loginNow() {
    const email = prompt('Enter your email');
    auth.login(email);
  }

  function getContent() {
    // Show a loading screen until we detect the login-state
    if (auth.loading || auth.loggingIn || auth.loggingOut) {
      return '...'
    }

    // Show this, if logged in
    if (auth.loggedIn) {
      return (
        <div>
          You are logged-in.
          <br/>
          <button onClick={() => auth.logout()}>Logout</button>
        </div>
      )
    }

    // Show this, if not logged-in
    return (
      <div>
        <button onClick={loginNow}>Login Now</button>
      </div>
    )
  }

  return (
    <div className="container">
      <main>
        <h1>Next.js Bank</h1>
        <div className="content">{getContent()}</div>
      </main>
    </div>
  )
}
It's that simple.

What about Data Fetching?

Having just the login-state in a client app is not enough. You may need to interact with a database, a CMS, or some APIs. With use-magic-link, that's pretty simple too.
Whenever you want to do an API call, use the fetch instance provides by the hook.
For example, here's how you can create a simple Bank statement that gets data from an API: (In this case, we use Next.js's built-in API routes)
import { useState, useEffect } from 'react';
import useMagicLink from 'use-magic-link'

export default function BankStatement() {
    const auth = useMagicLink('<Publishable Key>');
    const [statement, setStatement] = useState(null);

    useEffect(() => {
        if (auth.loggedIn) {
            auth.fetch('/api/statement')
                .then(res => res.json())
                .then((payload) => {
                    setStatement(payload);
                })
        }
    }, [auth.loggedIn])

    if (!auth.loggedIn) {
        return (<div>Not Authorized!</div>)
    }

    if (statement === null) {
        return (<div>Checking your statement ...</div>)
    }

    return (
        <div>
            Hello "{statement.email}", your balance is: {statement.balance} USD.
        </div>
    )
}
You can put this "BankStatement" component anywhere in your app.
Inside the Next.js API route, we need to authenticate the request and here's how we are doing it:
import { Magic } from '@magic-sdk/admin'
const magic = new Magic('<Magic Secret Key>')

function sendError(res, error) {
  console.error(error.stack);
  res.statusCode = 401
  res.json({
    error: {
      message: 'Unauthorized'
    }
  })
}

export default async (req, res) => {
  const magicToken = (req.headers.authorization || '').replace('Bearer ', '')
  try {
    // Authorize the request
    const metadata = await magic.users.getMetadataByToken(magicToken)
    
    // send the statement
    res.statusCode = 200
    res.json({ balance: 3000, email: metadata.email })
  } catch (err) {
    sendError(res, err)
  }
}
You need to install the @magic-sdk/admin NPM module and get the "Secret Key" from the Magic Link dashboard.
Here's the final result:

With "use-magic-link" React hook, we can add a login system to your React app in a few minutes. It saves your time to do things that matter.