Last active
December 28, 2021 22:37
-
-
Save abdulbasetbasher/9bfa326da80733ec8c02c032c9e090ba to your computer and use it in GitHub Desktop.
Server side Remix.js protected routes with supabase
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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> | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 | |
}) | |
} | |
}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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