0

I am working on integrating OAuth in my Next.js project using Supabase and "@supabase/ssr". I've successfully implemented MagicLink and email authentication, but I'm facing issues with OAuth. The authentication process seems to halt unexpectedly when I try to sign in using a social provider like Google.

async function signInWithEmail(formData: FormData) {
    "use server"

    const origin = headers().get("origin")
    const email = formData.get("email") as string
    const cookieStore = cookies()
    const supabase = createClient(cookieStore)

    const { error } = await supabase.auth.signInWithOtp({
      email: email,
      options: {
        emailRedirectTo: `${origin}/auth/callback`,
      },
    })

    if (error) {
      console.error(error)
      return redirect("/login?message=Could not authenticate user")
    }

    redirect("/login?message=Check your email inbox to continue signing in")
  }

with this callback:

import { createClient } from "@/lib/supabase/server"
import { NextResponse } from "next/server"
import { cookies } from "next/headers"

export async function GET(request: Request) {
  const requestUrl = new URL(request.url)
  const code = requestUrl.searchParams.get("code")

  if (code) {
    const cookieStore = cookies()
    const supabase = createClient(cookieStore)
    await supabase.auth.exchangeCodeForSession(code)
  }

  return NextResponse.redirect(requestUrl.origin)
}

lib/supabase/server.ts:

import { createServerClient, type CookieOptions } from "@supabase/ssr"
import { cookies } from "next/headers"

export const createClient = (cookieStore: ReturnType<typeof cookies>) => {
  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        get(name: string) {
          return cookieStore.get(name)?.value
        },
        set(name: string, value: string, options: CookieOptions) {
          try {
            cookieStore.set({ name, value, ...options })
          } catch (error) {
            console.error(error)
          }
        },
        remove(name: string, options: CookieOptions) {
          try {
            cookieStore.set({ name, value: "", ...options })
          } catch (error) {
            console.error(error)
          }
        },
      },
    }
  )
}

This is the function I'm trying to use to get Oauth to work:

  async function signInWithSocialProvider(provider: any) {
    "use server"

    const origin = headers().get("origin")
    const cookieStore = cookies()
    const supabase = createClient(cookieStore)

    const { error } = await supabase.auth.signInWithOAuth({
      provider: provider,
      options: {
        redirectTo: `${origin}/auth/callback`,
      },
    })

    if (error) {
      console.error(error)
      return redirect("/login?message=Could not authenticate user")
    }
  }

Questions:

  1. Is there something I'm missing in the OAuth setup with Supabase and SSR?

  2. Could there be a configuration issue within Supabase or in my Next.js setup causing this behavior?

Any insights or suggestions to resolve this issue would be greatly appreciated.

Expected Behavior: After choosing to sign in with a social provider (e.g., Google), I expect to be redirected to the provider's sign-in page and then back to my application with the user authenticated.

Actual Behavior: The authentication process does not proceed beyond the initial OAuth request. When I log the name and value in the set function within createServerClient, I receive a token, but there's no redirection to the Google sign-in page, and the authentication does not complete.

Logs:

  • Name: sb-mlirbfytwbmtpcchmvlr-auth-token-code-verifier

  • Value: "d8d738ef35947d057b013bb19adaee03e44d74003c47ea27b8426b59df264ece2a9f98f78fbdfc5d3e562f021bdf0e0460b633246e889b6c"

Solution:

Adding redirect(data.url) as the last line within the signInWithSocialProvider function solved the issue. Here is the full function:

async function signInWithSocialProvider(provider: any) {
    "use server"

    const origin = headers().get("origin")
    const cookieStore = cookies()
    const supabase = createClient(cookieStore)

    const { data, error } = await supabase.auth.signInWithOAuth({
      provider: provider,
      options: {
        redirectTo: `${origin}/auth/callback`,
      },
    })

    if (error) {
      console.error(error)
      return redirect("/login?message=Could not authenticate user")
    }

    redirect(data.url)
  }

1 Answer 1

1

There is no way for the redirect to happen automatically on the server as each server-side framework has a different way of handling redirects. In the browser there is only one API to redirect so this can be hardcoded into the supabase-js library. You will need to get the data property back from the function and redirect to the data.url with the method Next.js provides for redirecting. You can read more here https://github.com/orgs/supabase/discussions/15862

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much! It was exactly the solution to my issue. I have updated the original description to provide solution for others.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.