next.jsgoogle-oauthvercelproduction-environmentsupabase

Supabase google provider not working as expected in vercel deployed website


I am making a Nextjs project using Supabase. Throughout the development process I (and another developer working with me) used local Supabase instance and I had to change my supabase related env variables from the remote supabase values to the local supabase values. I am using supabase's google oauth provider. During the development the google authentication process was working well.

When I deployed the project on Vercel, the values of the env variables I used were those of the remote Supabase and not the local ones. As for the google client id and secret, I created a new separate project on google console where the value of the redirect url is the callback value given by Supabase in my remote Supabase. And the env values for the client id and secret I gave in the Vercel deployment were of this project and not the one I was using in my development.

But I don't know why my google authentication is not working in my deployed website. When I click the sign in and continue button after choosing a google account to sign in from, I get redirected to the localhost URL: http://localhost:3000/?code=40e25cab-f6b2-466a-8f61-7ac27128ccbe

in my browser console my browser console

Now here are the response and request headers of the network calls

General

Request URL: https://mumlxsmdqylggqktbgvb.supabase.co/auth/v1/callback?state=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTQ5NzkyNjUsInNpdGVfdXJsIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwIiwiaWQiOiIwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAiLCJmdW5jdGlvbl9ob29rcyI6bnVsbCwicHJvdmlkZXIiOiJnb29nbGUiLCJyZWZlcnJlciI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzAwMCIsImZsb3dfc3RhdGVfaWQiOiI2YmI3YjgxMC0xNmJkLTRhY2EtODliNy03MmFhYjQ1NDE0Y2YifQ.ERh_o2IwWhYzKcqPGxiM4K3rKHexN1IhUJ_WzLqe-iE&code=4%2F0AdLIrYedV-WyTJXW99bndYHlxnw9tBpHnOs8SNWwQbdKs00TW6YoFAYT9xBta9n6I8vAGw&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=0&prompt=consent
Request Method: GET
Status Code: 302 Found
Remote Address: 172.64.149.149:443
Referrer Policy: origin

Request Headers

:authority: mumlxsmdqylggqktbgvb.supabase.co
:method: GET
:path: /auth/v1/callback?state=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTQ5NzkyNjUsInNpdGVfdXJsIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwIiwiaWQiOiIwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAiLCJmdW5jdGlvbl9ob29rcyI6bnVsbCwicHJvdmlkZXIiOiJnb29nbGUiLCJyZWZlcnJlciI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzAwMCIsImZsb3dfc3RhdGVfaWQiOiI2YmI3YjgxMC0xNmJkLTRhY2EtODliNy03MmFhYjQ1NDE0Y2YifQ.ERh_o2IwWhYzKcqPGxiM4K3rKHexN1IhUJ_WzLqe-iE&code=4%2F0AdLIrYedV-WyTJXW99bndYHlxnw9tBpHnOs8SNWwQbdKs00TW6YoFAYT9xBta9n6I8vAGw&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=0&prompt=consent
:scheme:https
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7

Response Headers

Location:
http://localhost:3000?code=0e068715-35e2-4b92-9a4a-43906ba97042

The login button in my code:

'use client';

import { createSupabaseBrowserClient } from '@/lib/supabase/browser-clients';

import { Button } from '@/components/ui/button';

export default function LoginWithGoogleButton(props: { nextUrl?: string }) {

  const supabase = createSupabaseBrowserClient();

  const handleLogin = async () => {
    await supabase.auth.signInWithOAuth({
      provider: 'google',
      options: {
        redirectTo: `${location.origin}/api/auth/callback?next=${
          props.nextUrl || ''
        }`,
        queryParams: {
          access_type: 'offline',
          prompt: 'consent',
        },
      },
    });
  };

  return (
    <Button size='sm' onClick={handleLogin}>
      Login with Google
    </Button>
  );
}

api/auth/callback/route.ts

import { NextResponse } from 'next/server';

import { createSupabaseServerClient } from '@/lib/supabase/server-clients';

export async function GET(request: Request) {
  const { searchParams, origin } = new URL(request.url);

  const code = searchParams.get('code');

  // if "next" is in param, use it in the redirect URL
  // const next = searchParams.get('next') ?? '/';

  if (code) {
    const supabase = createSupabaseServerClient();

    const { error } = await supabase.auth.exchangeCodeForSession(code);

    if (!error) {
      return NextResponse.redirect(origin);
    }
  }

  // TODO:
  // return the user to an error page with instructions
  return NextResponse.redirect(`${origin}/auth/auth-error`);
}

I don't know why my response is coming from localhost. I have checked the env variables, redirect URL and everything, I can't seem to debug the problem.


Solution

  • Might not be the exact same scenario. But I was also using SupaBase and OAuth with Github. I set up the callback in the OAuth app to Supabase's and it was stuck after authenticating.

    Turns out, I needed to configure the Site URL to be where I deployed by app, which was Netlify (Authentication > URL Configuration > Site URL). After that, it worked.