Published on

How to Integrate LoginLlama with Next.js and Supabase

LoginLlama is a free service that helps you spot suspicious logins. It's easy to integrate and works with any platform.

Next.JS is an immensely popular full stack framework from Vercel. It's a great choice for building your next application. In fact, it's used to build LoginLlama itself! Supabase is an open source Firebase alternative. It handles all your authentication and database needs. Again, LoginLlama also uses this.

Dogfooding is a great way to test your product. So I decided to finally integrate LoginLlama with Next.js and Supabase. Here's how I did it. I was able to integrate LoginLlama in around 15 minutes. You can sign up for an always-free account here.

This guide assumes you already have Supabase and Next.js setup. And uses the @supabase/auth-ui-react library.

Step 1: Create a Free LoginLlama account + Grab your API key

First, you'll need to create a free LoginLlama account. You can sign up here. After logging in, you'll need to grab your API key. You can find this by clicking the person icon on the left hand side, then clicking "API Keys". Copy this value and add it to your .env file as LOGINLLAMA_API_KEY.

Step 2: Add the LoginLlama SDK

You can install the NodeJS SDK by running

npm install -s loginllama

yarn add loginllama

Step 3: Add the LoginLlama check on your backend

Under /pages/api create a new file called check-login.ts. Add the contents below. It's a simple API route that grabs information about the request and sends it to LoginLlama.

import { NextRequest } from 'next/server';
import { LoginLlama } from 'loginllama';

export default async function handler(req: NextRequest, res) {
  // The API key is automatically taken from the environment
  const loginllama = new LoginLlama();
  const { body } = req;
  // @ts-ignore
  const { user } = body;
  let ip =
    // @ts-ignore
    req.headers['x-forwarded-for'] || req.socket.remoteAddress || 'Unavailable';

  // If 'x-forwarded-for' contains multiple IPs, take the first one
  if (ip.includes(',')) {
    ip = ip.split(',')[0];
  }

  const loginInfo = {
    identity_key: user.id,
    ip_address: ip,
    user_agent: req.headers['user-agent'],
    email_address: user.email
  };

  try {
    const { status } = await loginllama.check_login(loginInfo);
    return status;
  } catch (err) {
    return res.json({ message: "Couldn't check login" });
  }
}

Step 4: Add the LoginLlama check on your frontend

Next, we need to add the LoginLlama check to our frontend. This is done after the user has logged in, but before redirecting to your account/dashboard page. In your pages/login.tsx file, add the following code.

import { useRouter } from 'next/router';
import { useEffect } from 'react';
import { useUser, useSupabaseClient } from '@supabase/auth-helpers-react';
import { Auth, ThemeSupa } from '@supabase/auth-ui-react';

const SignIn = () => {
  const router = useRouter();
  const user = useUser();
  const supabaseClient = useSupabaseClient();

  const checkLogin = async (user) => {
    try {
      // Send the request to your backend which then feeds the request to LoginLlama
      await fetch('/api/check-login', {
        method: 'POST',
        headers: new Headers({ 'Content-Type': 'application/json' }),
        credentials: 'same-origin',
        body: JSON.stringify({ user })
      });
    } catch (error) {
      console.error('Error fetching checking login:', error);
    }
  };

  useEffect(() => {
    if (user) {
      checkLogin(user);
      router.replace('/account');
    }
  }, [user]);

  if (!user)
    return (
      <Auth
        supabaseClient={supabaseClient}
        view="sign_in"
        providers={['github']}
        redirectTo={'http://localhost:3000/account'}
        magicLink={true}
        appearance={{
          theme: ThemeSupa,
          variables: {
            default: {
              colors: {
                brand: '#404040',
                brandAccent: '#52525b'
              }
            }
          }
        }}
        theme="dark"
      />
    );

  return (
    <div className="m-6">
      <h1>You are already logged in!</h1>
    </div>
  );
};

export default SignIn;

Step 5: Test it out

Start up your application (next dev) and then login. You should see a new login appear in your LoginLlama dashboard within a few seconds.

Conclusion

And that's it! You've now integrated LoginLlama with Next.js and Supabase. You can now track your users logins and spot suspicious activity. We will notify your customers via email if we detect a suspicious login. Alternatively, you can grab the response from LoginLlama and handle it yourself.