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()
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.
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
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.
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:
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
Next, install the Supabase JS library using either NPM or Yarn:
npm install @supabase/supabase-js
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:
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
}
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;
Now, we should be able to run the app and have a basic authentication flow set up for us:
npm start
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.