Remix and Supabase Authentication

How to secure a Remix and Supabase application using Row Level Security

Thursday, December 9, 2021

lock

NOTE: This tutorial is deprecated in favor of the official documentation.

Table of Contents


TL;DR: Source and Demo

Here's a live demo

Link to the source code

Link to step by step commits


Introduction

This blog will focus on securing our Remix application with Supabase's Row Level Security (RLS) feature. If you want to know the context of what application I'm talking about, you can refer to my another blog.


Setting up Supabase

Instead of updating my database from the previous blog, I'm just going to re-create it.

Create a table to contain user_id


Add a foreign key in user_id pointing to auth.users


Create Row Level Security Supabase Policies


Implement server-side utilities to manage Supabase session

Create server instance of Supabase client


Use createCookieSessionStorage to help in managing our Supabase token


Create a utility to set the Supabase token from the Request


Setting up authentication in the Remix side

Create client-side utilities for managing Supabase session

Create Supabase Provider and a custom hook which returns the Supabase instance


Pass Supabase environment variables to our client


Create a Supabase instance and pass it into the root level Supabase provider


Create the /auth route

Since I'm too lazy to implement a login page, I'll just use the UI provided by Supabase.

Install @supabase/ui


Create the main auth component

You can create your custom sign-up and sign-in form if you want.


Create the component to inform the server that we have a Supabase session


Create an action handler to process the Supabase token

After logging in, the user will be redirected to the /words route.


If you want to test without signing up, use the following credentials:

email: dev.codegino@gmail.com

password: testing


Signing out

Create a logout button in the header


Create an action handler

I don't want to pollute my other route, so I will create my signout action handler separately


TL;DR version of using our setup

Using in a loader or action


Conditional rendering based on auth state


NOTE: Conditional server-side rendering might cause hydration warning,

I'll fix this in another blog post.


Using in CRUD Operations

The examples below are a longer version of using our setup for CRUD operations.

Fetching All operation


Retrieve one and Delete one operation


Create operation


Update operation


Conclusion

We can still use Supabase only on the client-side as we use it on a typical React application. However, putting the data fetching on the server-side will allow us to benefit from a typical SSR application.