DEV Community

Cover image for 10 Minute Tutorial - Full Stack GitHub Authentication with Supabase & React
Nader Dabit
Nader Dabit

Posted on

10 Minute Tutorial - Full Stack GitHub Authentication with Supabase & React

In this post I want to show how quickly and easily GitHub authentication can be enabled with Supabase and React, a full stack project in around 50 lines of code.

The video for this tutorial is available here

As I've mentioned before, one of the reasons I like Supabase is the wide variety of authentication providers it give you out of the box.

Also, the APIs for interacting with them are about as simple as it gets:

/* authenticate */
const { user, session, error } = await supabase.auth.signIn({
  provider: 'github'
});

/* request signed in user */
const user = supabase.auth.user()
Enter fullscreen mode Exit fullscreen mode

As a developer, GitHub authentication is something you'll probably want to offer for any developer-facing product or service you create. Let's look at how we can set this up in just a few minutes and not much code with Supabase and React.

You can view all of the Supabase Authentication guides here at any time.

Creating the Supabase project

To get started, visit app.supabase.io and create a new project.

Once you've created your project, click on Settings in the left hand menu, then click API. Here, copy the project URL to your clipboard and then move on to the next step.

Supabase App URL

Creating the GitHub app

Next we need to create the GitHub OAuth application. To do so, click here and then click "Register a new Application".

Here, we can give the app a name, homepage url (http://localhost:3000 for now), and for the callback, use the Supabase app URL copied to your clipboard, appended with /auth/v1/callback:

https://<project-id>.supabase.co/auth/v1/callback
Enter fullscreen mode Exit fullscreen mode

Once you create the OAuth App, you should be given both a Client ID as well as a way to create a new client secret.

App ID & Secret

Create the client secret then move on to the next step.

Configuring the OAuth settings in Supabase

In the Supabase dashboard, click on Authentication in the left hand menu, then Settings and toggle the Github enabled switch. Here you should be able to configure your GitHub client ID as well as the GitHub secret:

Supabase Credentials

Your Supabase project is now ready to be used in your front end app!

Building the front end

Now that the Supabase project is ready to go, let's create the front end.

We'll be using React, but these ideas can be applied using any front end framework without a ton of fundamental changes.

First, create a new React project and change into the new directory:

npx create-react-app my-supabase-app

cd my-supabase-app
Enter fullscreen mode Exit fullscreen mode

Next, install the Supabase JS library using either NPM or Yarn:

npm install @supabase/supabase-js
Enter fullscreen mode Exit fullscreen mode

Next, we need to configure the Supabase project in our client application.

To do so, it's nice to have a separate configuration file that we we can import and use anywhere in our app. Create a new file in the src directory named client.js.

Here, we'll need the Supabase App URL as well as the anon public API Key from your project.

You can get these values from your Supabase project by clicking on Settings and then API:

API Key and Config URL

Using these values, create and export your Supabase client configuration:

/* src/client.js */
import { createClient } from '@supabase/supabase-js'

const supabase = createClient('https://appid.supabase.co', 'anon-public-key')

export {
  supabase
}
Enter fullscreen mode Exit fullscreen mode

Now we can start interacting with our Supabase app by importing this client!

Next, update src/App.js with the following code:

import './App.css';
import { useState, useEffect } from 'react';

import { supabase } from './client';

function App() {
  const [user, setUser] = useState(null);
  useEffect(() => {
    /* when the app loads, check to see if the user is signed in */
    checkUser();
    /* check user on OAuth redirect */
    window.addEventListener('hashchange', function() {
      checkUser();
    });
  }, [])
  async function checkUser() {
    /* if a user is signed in, update local state */
    const user = supabase.auth.user();
    setUser(user);
  }
  async function signInWithGithub() {
    /* authenticate with GitHub */
    await supabase.auth.signIn({
      provider: 'github'
    });
  }
  async function signOut() {
    /* sign the user out */
    await supabase.auth.signOut();
    setUser(null);
  }
  if (user) {
    return (
      <div className="App">
        <h1>Hello, {user.email}</h1>
        <button onClick={signOut}>Sign out</button>
      </div>
    )
  }
  return (
    <div className="App">
      <h1>Hello, please sign in!</h1>
      <button onClick={signInWithGithub}>Sign In</button>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Now, we should be able to run the app and have a basic authentication flow set up for us:

npm start
Enter fullscreen mode Exit fullscreen mode

Next steps

Right now we do not have a way to query for the users of our application.

We can set this up pretty easily by following this guide to create a profiles table referencing id in the auth.users table using a user_id field, and then setting row level access rules for reading and writing.

Discussion (2)

Collapse
goranpaunovic profile image
Goran Paunović

What is the reason for using 'hashchange' event listener and not Supabase onAuthStateChanged?

Collapse
ajcwebdev profile image
anthony-campolo