I’m having an issue when in my Next.js application when trying to fetch data via a route handler.
My database has a users table that contains an ID called user_id
that matches the uid of the authenticated user, and aps_id
which I use to make a call to a 3rd party API.
If I do not have RLS enabled on the table, I get the row returned as expected when I do a match for user ID.
If I have RLS enabled with the rule auth.uid() = user_id
I get no rows returned.
I have the following code in my route handler:
route.ts
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs';
import { cookies } from 'next/headers';
import { NextResponse } from 'next/server';
export async function GET() {
try {
const supabase = createRouteHandlerClient({ cookies });
const { data: userData } = await supabase.from('users').select('aps_id').single();
const apsId = userData?.aps_id;
const {
data: { user },
} = await supabase.auth.getUser();
console.log(user); // no user being returned?
const res = await fetch(process.env.APS_API_URL + 'ClientEligibility/' + apsId, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'apiKey': process.env.APS_API_KEY || ''
}
});
const data = await res.json();
console.log(data); // this is null, but it should be returning a row?
return NextResponse.json({ data });
} catch(e) {
console.error(e);
return NextResponse.json({ error: e }, { status: 500 });
}
}
It seems like there’s no user session data coming back, so I assume auth.uid() in the RLS policy is also resulting in null.
Is there another necessary step required to get the user session in a route handler?
If I do not have RLS enabled on the table, I get the row returned as expected when I do a match for user ID.
If I have RLS enabled with the rule auth.uid() = user_id
I get no rows returned.
2
Answers
I found an article by Jon Meyers at Supabase shortly after posting this which explains the issue (not really an issue, but intented behavior):
https://jonmeyers.io/blog/forwarding-cookies-from-server-components-to-route-handlers-with-next-js-app-router
TL;DR: manually add headers to your fetch request using next/headers:
The Row-Level Security (RLS) issue in your Next.js application may be remedied by ensuring that you are fully authorized before accessing the protected resources in the Supabase database. You are attempting to get data from your Supabase database in your code. This implies that you must ensure that the user is authorized and that the authentication token is given to Supabase along with the request. Before visiting the route, ensure that your users are properly authorized. Using Supabase’s authentication library, you should determine if the user is authenticated. When sending a request to your Next.js route handler, include the authentication token in the request.