Need help with API security
Unanswered
Northeast Congo Lion posted this in #help-forum
Northeast Congo LionOP
I am new to Next.js and I'm still learning about how to properly secure your API keys in prod. This is my question:
I have a supabase connected to my next.js project and i use drizzle ORM to communicate with it. I use supabase for auth, and i wanted to set up my own "Users" table with a foreign key to "auth.users.id" table in supabase. This was my idea of a service function:
services/handle_new_user.ts:
Now, the db client is this:
it loads up the env variable meaning it should never be run client side, so "use server" should always be set.
The idea was for this function to be apart of the already provided supabase signup function. Note: supabase has a public api key that is used when connecting to supabase client, also it's run in client side. Part of the sign-up section looks like this:
I have a supabase connected to my next.js project and i use drizzle ORM to communicate with it. I use supabase for auth, and i wanted to set up my own "Users" table with a foreign key to "auth.users.id" table in supabase. This was my idea of a service function:
services/handle_new_user.ts:
'use server';
// services/handle_new_user.ts
import { db } from "@/lib/drizzle/db"; // your drizzle db client instance
import { user } from "@/db/migrations/schema";
import type { UserInsert } from "@/db/types";
export async function handleNewAuthUser(authUser: { id: string; email: string }) {
const profile: UserInsert = {
authId: authUser.id,
email: authUser.email,
};
await db.insert(user).values(profile);
}Now, the db client is this:
import 'dotenv/config'
import { drizzle } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
const connectionString = process.env.DIRECT_URL!
// Disable prefetch as it is not supported for "Transaction" pool mode
export const client = postgres(connectionString, { prepare: false })
export const db = drizzle(client);it loads up the env variable meaning it should never be run client side, so "use server" should always be set.
The idea was for this function to be apart of the already provided supabase signup function. Note: supabase has a public api key that is used when connecting to supabase client, also it's run in client side. Part of the sign-up section looks like this:
8 Replies
Northeast Congo LionOP
'use client'
import { cn } from '@/lib/utils'
import { createClient } from '@/lib/supabase/client'
import Link from 'next/link'
import { useRouter } from 'next/navigation'
import { useState } from 'react'
import { handleNewAuthUser } from '@/services/handle_new_user'
export function SignUpForm({ className, ...props }: React.ComponentPropsWithoutRef<'div'>) {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [repeatPassword, setRepeatPassword] = useState('')
const [error, setError] = useState<string | null>(null)
const [isLoading, setIsLoading] = useState(false)
const router = useRouter()
const handleSignUp = async (e: React.FormEvent) => {
e.preventDefault()
const supabase = createClient()
setIsLoading(true)
setError(null)
if (password !== repeatPassword) {
setError('Passwords do not match')
setIsLoading(false)
return
}
try {
const { data, error } = await supabase.auth.signUp({
email,
password,
options: {
emailRedirectTo: `${window.location.origin}/protected`,
},
})
if (error) throw error
if (data.user) {
await handleNewAuthUser({ id: data.user.id, email: data.user.email! }) //!!!!!!!!<-
router.push('/auth/sign-up-success')
}
} catch (error: unknown) {
setError(error instanceof Error ? error.message : 'An error occurred')
} finally {
setIsLoading(false)
}
}So the entire sign up page is client side and inside it im calling handleNewAuthUser which is an async server side function. This is how i call it in the same page:
<CardContent>
<form onSubmit={handleSignUp}>
<div className="flex flex-col gap-6">
<div className="grid gap-2">
... ... ...Is this safe? Will my env variables stay safe this way? Is basically the answer "if .env call is in server side, you cant do anything to it to make it show in broswer, even wrap it in client side function"
I tried looking up the docs but couldn't find a definitive answer
Yes its safe, unless you add NEXT_PUBLIC as prefix.
DIRECT_URI —— Safe : Not exposed at client
NEXTPUBLIC DIRECT_URI — —Unsafe : Exposed at client
NEXTPUBLIC DIRECT_URI — —Unsafe : Exposed at client
@Abhii Yes its safe, unless you add NEXT_PUBLIC as prefix.
Northeast Congo LionOP
thank u so much
so pretty much there is no way ur apis get leaked if they dont have NEXT_PUBLIC?
Yep 👍