Skip to content

Instantly share code, notes, and snippets.

@abdulbasetbasher
Last active December 28, 2021 22:37
Show Gist options
  • Save abdulbasetbasher/9bfa326da80733ec8c02c032c9e090ba to your computer and use it in GitHub Desktop.
Save abdulbasetbasher/9bfa326da80733ec8c02c032c9e090ba to your computer and use it in GitHub Desktop.
Server side Remix.js protected routes with supabase
// app/context/auth.js
/*
when supabase auth state changed we sent request with event type and access token to api endpoint
to set or delete cookie using useFetcher
https://remix.run/docs/en/v1/api/remix#fetchersubmit
*/
import { createContext, useEffect, useState } from 'react'
import { useAuthStateChange, useClient } from 'react-supabase'
import { useFetcher } from "remix";
const initialState = { session: null, user: null }
export const AuthContext = createContext(initialState)
export function AuthProvider({ children }) {
const client = useClient()
const [state, setState] = useState(initialState)
const fetcher = useFetcher();
useEffect(() => {
const session = client.auth.session()
setState({ session, user: session?.user ?? null })
}, [])
useAuthStateChange((event, session) => {
console.log(`Supbase auth event: ${event}`, session)
setState({ session, user: session?.user ?? null })
fetcher.submit({ event: event, access_token: session?.access_token}, { method: "post", action: "/api/auth" })
})
return <AuthContext.Provider value={state}>{children}</AuthContext.Provider>
}
// app/routes/api/auth.jsx
// we check event type and set cookie to access token if login event or delete cookie on logout event
import { json } from "remix";
import { token_cookie } from "~/lib/cookie.server";
export const action = async ({request}) => {
const body = await request.formData()
if (!body.get('event'))
return json({ok : false});
if (body.get('event') === 'SIGNED_IN') {
if (!body.get('access_token'))
return json({ok: false});
return json({ok:true}, {
headers: {
"Set-Cookie": await token_cookie.serialize(body.get('access_token'))
}
})
}
if (body.get('event') === 'SIGNED_OUT')
return json({ok:true}, {
headers: {
"Set-Cookie": await token_cookie.serialize(null, {
maxAge: -1
})
}
})
}
// app/routes/api/protected.js
// we give access to data if access token from cookie is valid
import {json} from "remix";
import {token_cookie} from "~/lib/cookie.server";
import {supabaseClient} from "~/lib/supabase";
export const loader = async ({request}) => {
const token = await token_cookie.parse(
request.headers.get("Cookie")
);
const { user, error} = await supabaseClient.auth.api.getUser(token)
if (error)
return json({"error":"you are not allowed to get this secret info"})
return json({"data": "my cat eats soup everyday"})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment