Supabase offers a tutorial on how to implement auth with Remix and Supabase.
Part of the tutorial is focused on client-side authentication where it even exposes the env variables SUPABASE_URL and SUPABASE_ANON_KEY in order to create a instance of supabase on the client-side.
Below is part of the refered tutorial code:
export const loader = async ({}: LoaderArgs) => {
const env = {
SUPABASE_URL: process.env.SUPABASE_URL!,
SUPABASE_ANON_KEY: process.env.SUPABASE_ANON_KEY!,
};
return json({ env });
};
export default function App() {
const { env } = useLoaderData<typeof loader>();
const [supabase] = useState(() =>
createClient<Database>(env.SUPABASE_URL, env.SUPABASE_ANON_KEY)
);
return (
<html lang="en">
<head>
<Meta />
<Links />
</head>
<body>
<Outlet context={{ supabase }} />
<ScrollRestoration />
<Scripts />
<LiveReload />
</body>
</html>
);
}
Observe that the loader is used to send the env variables to the client-site and there a supabase object is instanciated and distributed throughout the app via the root Outlet context.
Here is the tutorial I'm refering to: https://egghead.io/lessons/github-implement-authentication-for-supabase-with-oauth-and-github
Thank you.
Why not handle everything auth on the server-side?
Because when using Supabase the only thing you can do on the backend (logout wise) is to revoke the refresh token but this still leaves the user with the access token that can be used, usually, up to 1 hour.
This means that the only sure way to log out a user is to remove their locally stored keys.
Exposing SUPABASE_URL and SUPABASE_ANON_KEY would not be dangerous?
SUPABASE_URL is just your database public API endpoint, it's no different from any other API endpoint you would be using in your app. It all boils down if you have proper RLS policies configured (which by default, on protected tables, they are)
SUPABASE_ANON_KEY - can be used for anonymous access, again that depends on RLS policies, but configured properly it's harmless.