S
Supabase2w ago
IPS

I am not getting supabase user session cookies, even after ignoring hmr and .well-known endpoints

import { createServerClient } from "@supabase/ssr";
import { NextResponse, type NextRequest } from "next/server";

const publicRoutes = ["/", "/:slug"];
const protectedRoutes = ["/form", "/username"];

export async function updateSession(request: NextRequest) {
let supabaseResponse = NextResponse.next({
request,
});

const path = request.nextUrl.pathname

if (path.startsWith('/.well-known') || path.startsWith('/_next')) {
return supabaseResponse
}

const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!,
{
cookies: {
getAll() {
return request.cookies.getAll();
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value, options }) =>
request.cookies.set(name, value)
);
supabaseResponse = NextResponse.next({
request,
});
cookiesToSet.forEach(({ name, value, options }) =>
supabaseResponse.cookies.set(name, value, options)
);
},
},
}
);
console.log("Incoming cookies:", request.cookies.getAll())

const {
data: { user },
} = await supabase.auth.getUser();


console.log("path- :- " + path )
console.log("user- :- " + user )


if(!user){
if (protectedRoutes.includes(path) || (!publicRoutes.includes(path) && !path.match(/^\/[^/]+$/))) {

const url = request.nextUrl.clone()
url.pathname = '/'
return NextResponse.redirect(url)

}
if (user && path === '/') {
const url = request.nextUrl.clone()
url.pathname = '/form'
return NextResponse.redirect(url)
}
}

return supabaseResponse;
}
import { createServerClient } from "@supabase/ssr";
import { NextResponse, type NextRequest } from "next/server";

const publicRoutes = ["/", "/:slug"];
const protectedRoutes = ["/form", "/username"];

export async function updateSession(request: NextRequest) {
let supabaseResponse = NextResponse.next({
request,
});

const path = request.nextUrl.pathname

if (path.startsWith('/.well-known') || path.startsWith('/_next')) {
return supabaseResponse
}

const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!,
{
cookies: {
getAll() {
return request.cookies.getAll();
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value, options }) =>
request.cookies.set(name, value)
);
supabaseResponse = NextResponse.next({
request,
});
cookiesToSet.forEach(({ name, value, options }) =>
supabaseResponse.cookies.set(name, value, options)
);
},
},
}
);
console.log("Incoming cookies:", request.cookies.getAll())

const {
data: { user },
} = await supabase.auth.getUser();


console.log("path- :- " + path )
console.log("user- :- " + user )


if(!user){
if (protectedRoutes.includes(path) || (!publicRoutes.includes(path) && !path.match(/^\/[^/]+$/))) {

const url = request.nextUrl.clone()
url.pathname = '/'
return NextResponse.redirect(url)

}
if (user && path === '/') {
const url = request.nextUrl.clone()
url.pathname = '/form'
return NextResponse.redirect(url)
}
}

return supabaseResponse;
}
This is the reponse in console -
Incoming cookies: [ { name: '__next_hmr_refresh_hash__', value: '264' } ]
path- :- /
user- :- null
Incoming cookies: [ { name: '__next_hmr_refresh_hash__', value: '264' } ]
path- :- /
user- :- null
version -
"@supabase/ssr": "^0.7.0",
"@supabase/supabase-js": "^2.57.4",
"@supabase/ssr": "^0.7.0",
"@supabase/supabase-js": "^2.57.4",
Problem -
posted in comments
posted in comments
6 Replies
IPS
IPSOP2w ago
Since the post got "too long" for word count, here's the problem - I am supposed to get
sb-access-token
sb-access-token
cookies when I am redirected from oAuth to the
/form
/form
page. Since I only want authorized users to see that page I implemented a middleware function to check the user's authorization. But I am unable to do that. The user is returning null, even when logged in. According to a github thread, it was an issue with the cookies being sent, and when I console.logged the cookies, I only saw nextjs hot module cookies, no supabase cookies. I am not sure how to proceed with this.
IPS
IPSOP2w ago
Github thread - https://github.com/supabase/supabase/issues/24194#issuecomment-2725577116 but the difference is, in his case he is getting the access token cookies, I am not getting them at all
GitHub
"supabase.auth.getUser()" is returning a null user value in nextjs ...
Bug report I confirm this is a bug with Supabase, not with my own application. I confirm I have searched the Docs, GitHub Discussions, and Discord. Describe the bug const { data, error } = await su...
IPS
IPSOP2w ago
Yeah, that's where I copied the code from, it's not working, even when I paste as it is
import { createServerClient } from "@supabase/ssr";
import { NextResponse, type NextRequest } from "next/server";

export async function updateSession(request: NextRequest) {
let supabaseResponse = NextResponse.next({
request,
});

const path = request.nextUrl.pathname;

const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!,
{
cookies: {
getAll() {
return request.cookies.getAll();
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value, options }) =>
request.cookies.set(name, value)
);
supabaseResponse = NextResponse.next({
request,
});
cookiesToSet.forEach(({ name, value, options }) =>
supabaseResponse.cookies.set(name, value, options)
);
},
},
}
);

// Do not run code between createServerClient and
// supabase.auth.getUser(). A simple mistake could make it very hard to debug
// issues with users being randomly logged out.

// IMPORTANT: DO NOT REMOVE auth.getUser()

const {
data: { user },
} = await supabase.auth.getUser();

console.log("path - " + path);
console.log("User - " + user);
console.log(request.cookies.getAll());

if (!user && request.nextUrl.pathname === "/form") {
// no user, potentially respond by redirecting the user to the login page
const url = request.nextUrl.clone();
url.pathname = "/";
return NextResponse.redirect(url);
}


return supabaseResponse;
}
import { createServerClient } from "@supabase/ssr";
import { NextResponse, type NextRequest } from "next/server";

export async function updateSession(request: NextRequest) {
let supabaseResponse = NextResponse.next({
request,
});

const path = request.nextUrl.pathname;

const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!,
{
cookies: {
getAll() {
return request.cookies.getAll();
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value, options }) =>
request.cookies.set(name, value)
);
supabaseResponse = NextResponse.next({
request,
});
cookiesToSet.forEach(({ name, value, options }) =>
supabaseResponse.cookies.set(name, value, options)
);
},
},
}
);

// Do not run code between createServerClient and
// supabase.auth.getUser(). A simple mistake could make it very hard to debug
// issues with users being randomly logged out.

// IMPORTANT: DO NOT REMOVE auth.getUser()

const {
data: { user },
} = await supabase.auth.getUser();

console.log("path - " + path);
console.log("User - " + user);
console.log(request.cookies.getAll());

if (!user && request.nextUrl.pathname === "/form") {
// no user, potentially respond by redirecting the user to the login page
const url = request.nextUrl.clone();
url.pathname = "/";
return NextResponse.redirect(url);
}


return supabaseResponse;
}
Here's my code almost 95% same, just changed the path names and added console statements, that's it. But doesn't work
Ali Lee
Ali Lee2w ago
could you please share your code for auth?
IPS
IPSOP2w ago
login.tsx (this is in "/") root
"use client";
import { redirect } from "next/navigation";
import { supabase } from "../../lib/supabase-client";
import LogoutBtn from "../auth/session/logout";
import { UserAuthContext } from "../hooks/authContext";
import { useContext } from "react";

export default function Login() {
const handleLogin = async () => {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: "google",
options: {
redirectTo: "http://localhost:3000/auth/callback",
},
});

if (data.url) {
redirect(data.url);
}
};

const userAuthenticated = useContext(UserAuthContext);

const btnclass =
"border-1 p-2 pl-4 pr-4 cursor-pointer rounded-2xl hover:bg-gray-800 active:bg-gray-600 ";
return (
<>
<div>
{" "}
{/*Master Div */}
<div className="text-center">
<h1 className="mt-20 text-4xl">Best way </h1>
<h3 className="text-2xl italic">
Login {">"} create {">"} Publish. That's it!
</h3>
</div>
<div className="mx-auto w-[40vw] h-fit p-16 mt-10 flex flex-col items-center justify-center rounded-4xl bg-[#171717]">
<div className="flex flex-col items-center">
<h1 className="text-3xl mb-10">Get started!</h1>
</div>

{!userAuthenticated && (
<button className={`${btnclass} pb-4`} onClick={handleLogin}>
Continue with Google
</button>
)}

{userAuthenticated && <LogoutBtn />}
</div>
</div>
{/*Master Div */}
</>
);
}
"use client";
import { redirect } from "next/navigation";
import { supabase } from "../../lib/supabase-client";
import LogoutBtn from "../auth/session/logout";
import { UserAuthContext } from "../hooks/authContext";
import { useContext } from "react";

export default function Login() {
const handleLogin = async () => {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: "google",
options: {
redirectTo: "http://localhost:3000/auth/callback",
},
});

if (data.url) {
redirect(data.url);
}
};

const userAuthenticated = useContext(UserAuthContext);

const btnclass =
"border-1 p-2 pl-4 pr-4 cursor-pointer rounded-2xl hover:bg-gray-800 active:bg-gray-600 ";
return (
<>
<div>
{" "}
{/*Master Div */}
<div className="text-center">
<h1 className="mt-20 text-4xl">Best way </h1>
<h3 className="text-2xl italic">
Login {">"} create {">"} Publish. That's it!
</h3>
</div>
<div className="mx-auto w-[40vw] h-fit p-16 mt-10 flex flex-col items-center justify-center rounded-4xl bg-[#171717]">
<div className="flex flex-col items-center">
<h1 className="text-3xl mb-10">Get started!</h1>
</div>

{!userAuthenticated && (
<button className={`${btnclass} pb-4`} onClick={handleLogin}>
Continue with Google
</button>
)}

{userAuthenticated && <LogoutBtn />}
</div>
</div>
{/*Master Div */}
</>
);
}
route.ts
route.ts
import { NextResponse } from 'next/server'
// The client you created from the Server-Side Auth instructions
import { createClient } from '@/utils/supabase/server'

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 as the redirect URL
let next = searchParams.get('next') ?? '/'
if (!next.startsWith('/')) {
// if "next" is not a relative URL, use the default
next = '/'
}

if (code) {
const supabase = await createClient()
const { error } = await supabase.auth.exchangeCodeForSession(code)
if (!error) {
const forwardedHost = request.headers.get('x-forwarded-host') // original origin before load balancer
const isLocalEnv = process.env.NODE_ENV === 'development'
if (isLocalEnv) {
// we can be sure that there is no load balancer in between, so no need to watch for X-Forwarded-Host
return NextResponse.redirect(`${origin}${next}`)
} else if (forwardedHost) {
return NextResponse.redirect(`https://${forwardedHost}${next}`)
} else {
return NextResponse.redirect(`${origin}${next}`)
}
}
}

// return the user to an error page with instructions
return NextResponse.redirect(`${origin}/auth/auth-code-error`)
}
import { NextResponse } from 'next/server'
// The client you created from the Server-Side Auth instructions
import { createClient } from '@/utils/supabase/server'

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 as the redirect URL
let next = searchParams.get('next') ?? '/'
if (!next.startsWith('/')) {
// if "next" is not a relative URL, use the default
next = '/'
}

if (code) {
const supabase = await createClient()
const { error } = await supabase.auth.exchangeCodeForSession(code)
if (!error) {
const forwardedHost = request.headers.get('x-forwarded-host') // original origin before load balancer
const isLocalEnv = process.env.NODE_ENV === 'development'
if (isLocalEnv) {
// we can be sure that there is no load balancer in between, so no need to watch for X-Forwarded-Host
return NextResponse.redirect(`${origin}${next}`)
} else if (forwardedHost) {
return NextResponse.redirect(`https://${forwardedHost}${next}`)
} else {
return NextResponse.redirect(`${origin}${next}`)
}
}
}

// return the user to an error page with instructions
return NextResponse.redirect(`${origin}/auth/auth-code-error`)
}
utils/supabase/server.ts
utils/supabase/server.ts
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'

export async function createClient() {
const cookieStore = await cookies()

return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll()
},
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
)
} catch {
// The `setAll` method was called from a Server Component.
// This can be ignored if you have middleware refreshing
// user sessions.
}
},


},
}
)
}
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'

export async function createClient() {
const cookieStore = await cookies()

return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll()
},
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
)
} catch {
// The `setAll` method was called from a Server Component.
// This can be ignored if you have middleware refreshing
// user sessions.
}
},


},
}
)
}
My social login is working, it's saving the token in localStorage but this flow sends me to an error page and doesn't save the token in cookies Silly Mistake - in login.tsx import { supabase } from "../../lib/supabase-client"; should've been import { createClient } from "@/utils/supabase/client"; import from utils/supabase/client NOT supabase/server and ensure it's supabase/ssr not js Going to keep this up in case anyone makes the same mistake I made I don't know how to mark it resolved

Did you find this page helpful?