-
-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cookies not setting properly supabase ssr #36
Comments
Anyone have an idea or have the same issue? It is constantly happening so its either something in my sign up flow (which as far as I can tell is identical to the docs but I could be wrong), or an issue on supabase side.. either way would 1) need better docs or 2) is a bug in the ssr package which we have all been repeatedly told to upgrade to |
Can take a look at this |
Ok - I am unable to repro this, I am following the docs here and here , have tried both a magiclink and OTP. afaik whether you Also if anyone else more familiar wants to jump in please feel free to. |
So I did quite a bit more investigation (still have no clue where the issue is) - tested in both safari and firefox. Same issue - first logon pass it doesnt set the auth cookie properly, the second it does (and it stays set too). The auth-token is definitly coming through from request in the first instance - it is just not being set properly and i don't really know where it is being set.. I have tried to go through the code but I cannot see anywhere I would be eg. removing it (and if it was, it stays after the second log on everytime anyway). (only the auth-token-code-verifier is being set first pass) I did upgrade a while back from using auth-helper and js, so there could potentially be some legacy code from that, but I cannot find anything obvious at least and don't have those imports in my code anymore either. I have added a bunch of console.logs to the updateSession function to try and follow and see where the issues are. I also tried to set it manually (but when I set it manually it was actually removed (i saw the remove statements) the first pass then set properly the second. While the get function is definitly called many times (and especially on the first pass get finds auth-token) it is not finding auth-token upon page refresh.. (so I am guessing it is uing the headers originally, as it also does go to the dashboard but is just not being set properly). I cannot see anywhere I am deleting this cookie and have searched everywhere I am accessing the cookies too. I am not sure where the set functions are being called though - I don't get any console.logs from there at all... The remove I only ever saw 1 console log which was when I tried to set it myself manually. (even when the cookies are definitly being set). Is that on a different part of the supabase client maybe?
|
Ok super weird - I thought I was getting the error for about an hour but now it doesn't seem to want to reproduce, afaict there isn't an issue with the auth code exchange, and it only takes me 1 signup or login to see both cookies, if you upgraded from the recent auth-helpers it sounds like the main difference is the way the cookies and its properties are managed, there is this example of supabase auth with ssr, but from the above middleware I can't find anything wrong with it. Maybe it could be something to do with the legacy code but it sounds ilke you've done a full migration :/ There is a possibly related ticket here but it's hard to tell 🤷 , |
I have a similar issue. I think it has to do with how you are setting the cookies. For some reason we can only set a single If there is more then 1 cookie in the header then it seems to break the auth flow. I am trying to set a cookie for sharing auth with other micro services but it does not work and I have not figured out how to modify the auth cookie to be a base level domain try only setting a single cookie once per request |
Hm that makes sense! I guess there is a nextjs version that maybe has done this so maybe the issue is on the nextjs side not supabase's? Potentially this issue: vercel/next.js#64166 |
any fix on this? having the same issue |
So I'm not sure this is the same issue, but we had an issue related to cookies not getting set properly and logging us out, and removing
from the middleware, leaving just
fixed this for us. Would be interested if this works for others. |
@ThomasBurgess2000 thanks for great solution! Although this solution partially works for me. If you use backend server and you stay on same page for access token's expiration time, server will send you unauthorized error due to access token expiration. If you refresh the page or move to other pages, it works fine. Any idea? |
@koolerjaebee I have not encountered this myself, having only recently implemented this solution, but what you're saying is quite possible. I will try to circle back to this in the next few days to test and see if I can find a solution. My workaround is not ideal, because clearly it's not what supabase intended, so I'm hoping they will chime in at some point. Were you just setting the JWT expiration time really low to test? And then the behavior you're describing would happen consistently? |
Yes, I was setting JWT expiration time to 1 min so that I can see if there is another error. 1 hour was my original setting and actually not a big problem because not many people would stay in same page for that long. |
Any news ? I have the same issue with supabase ssr and last nextjs version :/ |
I fixed my issues by removing any auth stuff from server actions and putting them in routes. I think something with Next Caching causes bugs with the cookies |
still have an error event update to latest version of I did a quick fix that solved the error. const cookieStore = cookies();
const { data, error } = await repository.auth.signInWithPassword({
email,
password,
});
cookieStore.set('sb-access-token', data?.session?.access_token);
cookieStore.set('sb-refresh-token', data?.session?.refresh_token); When I try to capture user information in my API routes I've an auxiliary function: retrieveAuthOrSessionUser = async () => {
let userFinal = null;
const cookieStore = cookies();
const accessToken = cookieStore.get('sb-access-token');
const refreshToken = cookieStore.get('sb-refresh-token');
const {
data: { user },
error,
} = await this.supabase.auth.getUser();
if (error) {
const { data: dataSession } = await this.supabase.auth.setSession({
access_token: accessToken?.value ?? '',
refresh_token: refreshToken?.value ?? '',
});
userFinal = dataSession?.user;
} else {
userFinal = user;
}
const { id } = userFinal ?? {};
return {
id: id ?? '',
};
}; Remember to erase the cookies on the process of sign-out const supabaseCookies = cookies().getAll();
supabaseCookies.map((cookie) => {
if (cookie.name.includes('sb-')) {
cookies().delete(cookie.name);
}
}); isn't the best scenario or code, but does the job. Hope this Helps. |
I'm not familiar with Next, but has anyone tried migrating to the new ssr 0.4.x version and using the setAll and getAll methods? It's supposed to better handle Next quirkiness. New docs are available here |
For anyone having the issues - I think it is a nextjs issue. Updating nextjs solved it and I have not had this issue the past week (have been testing) |
To what version? |
Ye, for what version? |
Thanks a lot @Sof2222! For reference I upgraded from |
Same issue, any solutions? Next.js 14.2.5 doen't resolve this problem for me |
We are experiencing this exact same issue. Next version 14.2.5. |
In my case, I used |
This doesn't directly solve OP's problem, but just throwing this out there in case anyone's banging their head against the table. Make sure you don't have any logout links inadvertently getting prefetched. My supabase auth cookie was getting assigned correctly, but then NextJS would prefetch the logout link on my account page, causing the server to immediately delete the cookie. |
In the password reset case, with Next.js pages router on 14.2.5 and most recent versions of @supabase/ssr and @supabase/auth-js (at time of this post), I have this workaround: // @filename: src/pages/api/auth/confirm.ts
import { type EmailOtpType } from '@supabase/supabase-js';
import type { NextApiRequest, NextApiResponse } from 'next';
import { createClient } from '@/lib/utils/supabase/api';
import { serializeCookieHeader, stringToBase64URL } from '@supabase/ssr';
function stringOrFirstString(item: string | string[] | undefined) {
return Array.isArray(item) ? item[0] : item;
}
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
if (req.method !== 'GET') {
res.status(405).appendHeader('Allow', 'GET').end();
return;
}
const queryParams = req.query;
const token_hash = stringOrFirstString(queryParams.token_hash);
const type = stringOrFirstString(queryParams.type);
let next = '/error';
if (token_hash && type) {
const supabase = createClient(req, res);
const { error, data } = await supabase.auth.verifyOtp({
type: type as EmailOtpType,
token_hash,
});
if (error) {
console.error(error);
} else {
// Workaround for https://github.com/supabase/ssr/issues/36
const supabaseURL = new URL(process.env.NEXT_PUBLIC_SUPABASE_URL!);
const supabaseCookieDomainPrefix = supabaseURL.hostname.split('.')[0];
const authTokenCookie = {
name: `sb-${supabaseCookieDomainPrefix}-auth-token`,
value: `base64-${stringToBase64URL(JSON.stringify(data.session!))}`,
options: {
path: '/',
sameSite: 'lax',
httpOnly: false,
maxAge: 31536000000,
},
};
res.setHeader(
'Set-Cookie',
[authTokenCookie].map(({ name, value, options }) =>
serializeCookieHeader(name, value, options),
),
);
next = stringOrFirstString(queryParams.next) || '/';
}
}
res.redirect(next);
} Maybe I've configured something wrong, but this if statement never runs the if branch because setItem is never called with the code-verifier cookie as the key: Line 358 in ae6af1d
|
God thank you, I rarely use NEXTJS and I always forget to remove the prefetch behaviour |
@mattrigg9 you are a hero. thank you! |
@mattrigg9 I got caught by the exact same thing, thanks for the tip. In my case this was only happening in production since "Prefetching is not enabled in development, only in production." |
Why is everyone using Next.js...? I am having the same problem with Remix :( |
tldr; it may be worth checking for version incompatibilities between the Supabase libraries being used. i had this issue and resolved by making sure all supabase actions were using @supabase/ssr. It's possible you are using @supabase/auth-helpers-nextjs elsewhere in your app. Improper setting in the cookie likely stems from using different supabase client creation methods in different parts of your app. |
I have the same problem and I am using the latest version of the superbase client and also not using @supabase/auth-helpers-nextjs... My Quick fix(which still doesn't work for all my users) is to set the cookie manually |
You sir are a godsend, thank you! |
Bug report
I have already checked and cant see the same issue.
Describe the bug
I am using supabase-ssr package to log on.
I thought this was only an issue in dev mode as when I ran build mode on Friday it worked, but perhaps I had not properly deleted the cookie when I was testing so am getting the error again now.
Basically the auth-token cookie is not setting properly. If I log on twice, it sets but the first time i log on only sb-__-auth-token-code-verifier is set.
I am unsure if it is something on my side which is causing the error or if there is something timing out in the setting of the second cookie. My code is below.
Note I am using a otp sent to emails for this.
To Reproduce
This is to get the code:
This is the server component for createClient:
This is to check the OTP code:
I am redirected to the dashboard.
However the cookies are not being set properly. The first time:
sb--auth-token-code-verifier is set properly.
The second time I log on sb--auth-token is set
(Note this is called when someone is on protected:
I have tried with our without this: await supabase.auth.getUser();
But then what happens is I get thrown from the route a moment later or if I try to navigate and I am thrown out of the protected route.
I then have to log in again in which case the second cookie is set.
Expected behavior
That the cookies would all set in the first instance and the user is not required to log on twice for them to set
Screenshots
If applicable, add screenshots to help explain your problem.
System information
nextjs version - 14.1.4
Additional context
Add any other context about the problem here.
The text was updated successfully, but these errors were encountered: