Integrating With Supabase Auth
Integrate Supabase Auth with Edge Functions
Edge Functions work with Supabase Auth.
This allows you to:
- Automatically identify users through Legacy JWT tokens
- Enforce Row Level Security policies
- Integrate with your existing auth flow
Setting up auth context#
When a user makes a request to an Edge Function, you can use the Authorization header to set the Auth context in the Supabase client and enforce Row Level Security policies.
1import { createClient } from 'npm:@supabase/supabase-js@2'23Deno.serve(async (req: Request) => {4 const supabaseClient = createClient(5 Deno.env.get('SUPABASE_URL') ?? '',6 Deno.env.get('SUPABASE_ANON_KEY') ?? '',7 // Create client with Auth context of the user that called the function.8 // This way your row-level-security (RLS) policies are applied.9 {10 global: {11 headers: { Authorization: req.headers.get('Authorization')! },12 },13 }14 );1516 //...17})This context setting happens in the Deno.serve() callback argument, so that the Authorization header is set for each individual request scope.
Fetching the user#
By getting the JWT from the Authorization header, you can provide the token to getUser() to fetch the user object to obtain metadata for the logged in user.
1Deno.serve(async (req: Request) => {2 // ...3 const authHeader = req.headers.get('Authorization')!4 const token = authHeader.replace('Bearer ', '')5 const { data } = await supabaseClient.auth.getUser(token)6 // ...7})Row Level Security#
After initializing a Supabase client with the Auth context, all queries will be executed with the context of the user. For database queries, this means Row Level Security will be enforced.
1import { createClient } from 'npm:@supabase/supabase-js@2'23Deno.serve(async (req: Request) => {4 // ...5 // This query respects RLS - users only see rows they have access to6 const { data, error } = await supabaseClient.from('profiles').select('*');78 if (error) {9 return new Response('Database error', { status: 500 })10 }1112 // ...13})Example#
See the full example on GitHub.
1// Follow this setup guide to integrate the Deno language server with your editor:2// https://deno.land/manual/getting_started/setup_your_environment3// This enables autocomplete, go to definition, etc.45import { withSupabase } from 'npm:@supabase/server@^1'67console.log(`Function "select-from-table-with-auth-rls" up and running!`)89export default {10 fetch: withSupabase({ auth: 'user' }, async (req, ctx) => {11 try {12 // ctx.supabase runs queries as the authenticated user, so RLS applies.13 // ctx.userClaims holds the verified user identity.14 const { data, error } = await ctx.supabase.from('users').select('*')15 if (error) throw error1617 return Response.json({ user: ctx.userClaims, data })18 } catch (error) {19 return Response.json({ error: error.message }, { status: 400 })20 }21 }),22}2324// To invoke (auth: 'user' requires a signed-in user's access token):25// curl -i --location --request POST 'http://localhost:54321/functions/v1/select-from-table-with-auth-rls' \26// --header 'Authorization: Bearer <USER_ACCESS_TOKEN>' \27// --header 'Content-Type: application/json' \28// --data '{"name":"Functions"}'