Reputation: 99
I need help setting up custom auth with RLS on Supabase and NextJS;
I used the following tutorial to get me started but I quickly realized it was outdated.
I'm stuck at generating a JWT and starting a session for a user given that JWT. Since the removal of auth.setAuth()
I'm not too sure how to achieve my end goal in nextJS.
I have a public.users table with an id column which is a foreign key duplicate of the id column of auth.users.
RLS is enabled and with the following UPDATE check: (auth.uid() = id)
.
NOTE: this is a duplicate of a post I made on Github, I'm hoping to get more answers on SO... https://github.com/orgs/supabase/discussions/15612#discussioncomment-6396134
The documentation on the feature is pretty confusing so I'm hoping that my post helps someone else as confused as me;
Here is my code:
/api/auth/login.ts (simplified for readability)
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const { email } = req.body
// createPagesServerClient is from supabase's auth-helpers modules.
const supabaseServerClient = createPagesServerClient({
req,
res,
});
// getUserByEmail retrieves user by email from table 'public.users'
let user = await getUserByEmail(email, supabaseServerClient);
if(user){ // User already exists at this point
const newSecret = generateSecret(); // generats a random string
const token = genCookie(user,req,res) // See function genCookie below (generates the JWT)
supabaseServerClient.functions.setAuth(token)
supabaseServerClient.realtime.setAuth(token)
const {data:users,error} = await supabase
.from("users") // public.users table
.update({secret: newSecret })
.eq("email", email)
.select();
if(!user){
return res.status(422).json({ error: "Could not update user " + reconstructedAddress});
}
return res.send(users[0])
}else{
// error
}
}
function genCookie()
const genCookie = (user:SupabaseUser,req:IncomingMessage,res:ServerResponse)=>{
const token = jwt.sign({ id:user.id, email:user.email }, process.env.JWT_SECRET ); //JWT_SECRET is from the supabase dashboard
// user j4w8n from github suggested using `sub: user.id` instead of id, however this also didn't work...
return token
}
My issue is that the policy check clearly doesn't work since the query below returns error = null and users= [] (yet the user exists). So I assume my understanding of auth is completely wrong.
const {data:users,error} = await supabase
.from("users") // public.users table
.update({secret: newSecret })
.eq("email", email)
.select();
I'm really confused at how I can make auth work with custom jwt... I'd love some guidance. Also worth noting, I am using NextJS pages directory (not App directory);
"@supabase/auth-helpers-nextjs": "^0.7.2",
"@supabase/auth-helpers-react": "^0.4.0",
"@supabase/supabase-js": "^2.24.0",
Upvotes: 3
Views: 4653
Reputation: 99
Ok, I've found a partial solution, it looks like the auth-helper module needs to be updated so that the rest
headers are also updated;
I changed my code to add a one-line hack:
supabaseServerClient.functions.setAuth(token)
supabaseServerClient.realtime.setAuth(token)
;(supabaseServerClient as any).rest.headers.Authorization = `Bearer ${token}`
and now I can successfully edit the user data;
However I'm still not sure how to create a session with that jwt EDIT: (see my comment I figured it out)
Upvotes: 2