#Integrating supabase auth with Convex

1 messages · Page 1 of 1 (latest)

high blaze
#

I am adding Convex as a real-time data processor to an existing nextjs \ supabase app. How do I configure Convex to acknowledge the JWT issued by supabase?

edgy wigeonBOT
#

Hi @high blaze. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

To integrate Supabase authentication with Convex in your Next.js app, you'll need to implement a custom authentication solution. Convex doesn't have built-in support for Supabase auth, but you can use a self-signing approach similar to what's done with NextAuth. Here's a general outline of how you can approach this:

  1. Generate a public-private key pair for signing JWTs.

  2. Configure Convex to use the public key for verifying JWTs.

  3. Use the private key to sign a JWT on your Next.js server after validating the Supabase token.

  4. Pass this signed JWT to the Convex client for authentication.

Here's a more detailed breakdown:

  1. Generate keys and configure Convex:
    Follow the steps outlined in the NextAuth adapter guide (https://stack.convex.dev/nextauth-adapter#generate-the-keys) to generate a key pair and configure Convex with the public key.

  2. Set up your convex/auth.config.ts:

    export default {
      providers: [
        {
          domain: process.env.CONVEX_SITE_URL,
          applicationID: "convex",
        },
      ],
    };
    
  3. On your Next.js server, create a function to validate the Supabase token and issue a Convex JWT:

    import { SignJWT, importPKCS8 } from "jose";
    
    async function getConvexToken(supabaseToken) {
      // Validate Supabase token here
      // If valid, create and sign a JWT for Convex
      const privateKey = await importPKCS8(
        process.env.CONVEX_AUTH_PRIVATE_KEY!,
        "RS256"
      );
      const convexToken = await new SignJWT({
        sub: supabaseUserId, // Get this from Supabase token
      })
        .setProtectedHeader({ alg: "RS256" })
        .setIssuedAt()
        .setIssuer(process.env.CONVEX_SITE_URL)
        .setAudience("convex")
        .setExpirationTime("1h")
        .sign(privateKey);
      return convexToken;
    }
    
#
  1. Create an API route in Next.js to exchange the Supabase token for a Convex token:

    export default async function handler(req, res) {
      const supabaseToken = req.headers.authorization;
      const convexToken = await getConvexToken(supabaseToken);
      res.status(200).json({ convexToken });
    }
    
  2. On the client-side, use a custom useAuth hook to fetch and provide the Convex token:

    function useAuth() {
      const { supabaseToken } = useSupabaseAuth(); // Your Supabase auth hook
      const [convexToken, setConvexToken] = useState(null);
    
      useEffect(() => {
        if (supabaseToken) {
          fetchConvexToken(supabaseToken).then(setConvexToken);
        }
      }, [supabaseToken]);
    
      return {
        isAuthenticated: !!convexToken,
        fetchAccessToken: async () => convexToken,
      };
    }
    
  3. Use this custom useAuth hook with ConvexProviderWithAuth:

    <ConvexProviderWithAuth client={convex} useAuth={useAuth}>
      {children}
    </ConvexProviderWithAuth>
    

This approach is similar to the one described in the NextAuth adapter guide (https://stack.convex.dev/nextauth-adapter#issue-the-jwt), but adapted for Supabase. You'll need to implement the Supabase token validation and user ID extraction based on Supabase's documentation.

Remember, this is an advanced setup and requires careful implementation to ensure security. Always validate tokens properly and handle errors appropriately.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@high blaze Kapa.ai is still learning and improving, please let me know how I did by reacting below.

high blaze
#

@edgy wigeon - is it possible to have Convex read the JWT created by supabase? Perhaps something like this? import { defineAuth } from "convex/server";
import { verify } from "jsonwebtoken";

// Define your auth configuration
export default defineAuth({
// Create a verify function that validates Supabase JWTs
async verify(token: string) {
if (!token) {
return null;
}

try {
  // Verify the JWT using your Supabase JWT secret
  const decoded = verify(token, process.env.SUPABASE_JWT_SECRET);
  
  // Return the user information Convex should use
  return {
    id: decoded.sub, // Supabase user ID
    // Add any additional claims you want to pass to Convex
    email: decoded.email,
  };
} catch (error) {
  return null;
}

}
});

edgy wigeonBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

I apologize, but I don't have enough information to confirm if it's possible to have Convex directly read and verify JWTs created by Supabase in the way you've described. The knowledge sources provided don't contain specific information about integrating Supabase JWTs with Convex.

However, based on the available information, Convex typically requires a specific authentication setup. The closest approach I can suggest is similar to what's described in the NextAuth adapter guide (https://stack.convex.dev/nextauth-adapter#authenticating-convex-function-calls), where Convex uses its own JWT for authentication.

Instead of directly verifying Supabase JWTs, you might need to:

  1. Verify the Supabase JWT on your server.
  2. If valid, create a new JWT that Convex can understand and verify.
  3. Configure Convex to use this new JWT for authentication.

This approach would require you to set up a custom authentication flow, similar to what's described in the Custom Auth Integration (https://docs.convex.dev/auth/advanced/custom-auth) documentation.

If you need a definitive answer about directly using Supabase JWTs with Convex, I recommend reaching out to Convex support for the most up-to-date and accurate information.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: