Auto logout

Hi, Im using nextjs + mongodb and Redis for caching. But when I update the site, some users getting logged out. and some was saying that it takes a few minutes to login again.
18 Replies
Samy
SamyOP2mo ago
I think the problem is with secondary storage if it didn't find the data in secondary storage, it doesn't check on the db @Ping sorry for pinging but I really need to fix this fast
Ping
Ping2mo ago
Few minutes? Interesting. I'm pretty sure once you enable secondary stroage that it will default certain tables to that secondary storage DB. Your primary DB isn't a backup. So if it can't find the session in your Redis DB, it wouldn't search your primary. Was it that you recently enabled secondary storage? And you had some sessions on primary db previously?
Samy
SamyOP2mo ago
no, Im using secondary storage from the beginning, but I did switch to a new server can I make it so, if the session is not available on redis it will search the primary db?
Ping
Ping2mo ago
No I don't think so, unfortunately. Though it's not a bad idea for a feature.
Samy
SamyOP2mo ago
I hope you will add it in the future
bekacru
bekacru2mo ago
we should allow this if session.storeSessionInDatabase is set to true. Will ping you when it's changed
Samy
SamyOP2mo ago
ok thanks
bekacru
bekacru2mo ago
check v1.2.6-beta.1
Samy
SamyOP2mo ago
it still not working
export const auth = betterAuth({
database: mongodbAdapter(client),
secondaryStorage: {
get: async (key) => {
try {
const value = await getCache(key);
return value ? value : null;
} catch (error) {
console.error("Error getting from redis", error);
return null;
}
},
set: async (key, value, ttl) => {
try {
if (ttl) await setCache(key, value, { EX: ttl });
else await setCache(key, value, {});
} catch (error) {
console.error("Error setting to redis", error);
}
},
delete: async (key) => {
try {
await delCache(key);
} catch (error) {
console.error("Error deleting from redis", error);
}
},
},
})

export const getCache = async (key: string): Promise<string | null> => {
try {
if (process.env.REDIS_PASSWORD && process.env.REDIS_URL) {
await connectRedis();

const data = await redis.get(key);

if (data) {
return data;
}
}

return null;
} catch (error) {
console.error("Error getting cache", error);
return null;
}
};
export const auth = betterAuth({
database: mongodbAdapter(client),
secondaryStorage: {
get: async (key) => {
try {
const value = await getCache(key);
return value ? value : null;
} catch (error) {
console.error("Error getting from redis", error);
return null;
}
},
set: async (key, value, ttl) => {
try {
if (ttl) await setCache(key, value, { EX: ttl });
else await setCache(key, value, {});
} catch (error) {
console.error("Error setting to redis", error);
}
},
delete: async (key) => {
try {
await delCache(key);
} catch (error) {
console.error("Error deleting from redis", error);
}
},
},
})

export const getCache = async (key: string): Promise<string | null> => {
try {
if (process.env.REDIS_PASSWORD && process.env.REDIS_URL) {
await connectRedis();

const data = await redis.get(key);

if (data) {
return data;
}
}

return null;
} catch (error) {
console.error("Error getting cache", error);
return null;
}
};
in development If i add the secondary storage and don't provide the the redis url (then it will return null), and try to login, my account is not showing, it still only checking from secondary storage and if I remove secondary storage, it works fine
bekacru
bekacru2mo ago
make sure to enable session.storeSessionInDatabase
Samy
SamyOP2mo ago
it's working now thanks
Samy
SamyOP2mo ago
sorry but im using an electron app, im getting this error after client.signIn.social reading from http://localhost:3939/oauth/callback?state=s2pyqkoffSwCSX_lJhhvjropJ3uxbMu9&code=4%2F0AQSTgQFIub5p--00iY-ejLmokPBa-0rVHAY_p2pFQH1G3CxAfmribkZemhaAAfPsSBrG1A&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 I added http://localhost:3939/ in the trustedOrigins but still not working
No description
bekacru
bekacru2mo ago
see the server logs. this has to do with verification request to the provider returning an error.
Samy
SamyOP2mo ago
is there any way to ignore this error?
2025-03-27T09:28:53.484Z ERROR [Better Auth]: {
error: 'redirect_uri_mismatch',
error_description: 'Bad Request',
status: 400,
statusText: 'Bad Request'
}
2025-03-27T09:28:53.484Z ERROR [Better Auth]: {
error: 'redirect_uri_mismatch',
error_description: 'Bad Request',
status: 400,
statusText: 'Bad Request'
}
because in electron js, I need to change the redirect url to http://localhost:3939/oauth/callback to redirect back from the browser to app
session.defaultSession.webRequest.onBeforeRequest((details, callback) => {
const url = details.url;

if (url.includes("accounts.google.com")) {
let parsedUrl = new URL(url);
parsedUrl.searchParams.set(
"redirect_uri",
"http://localhost:3939/oauth/callback"
);

shell.openExternal(parsedUrl.toString());
callback({ cancel: true });
return;
}
})
session.defaultSession.webRequest.onBeforeRequest((details, callback) => {
const url = details.url;

if (url.includes("accounts.google.com")) {
let parsedUrl = new URL(url);
parsedUrl.searchParams.set(
"redirect_uri",
"http://localhost:3939/oauth/callback"
);

shell.openExternal(parsedUrl.toString());
callback({ cancel: true });
return;
}
})
bekacru
bekacru2mo ago
you should providehttp://localhost:3939/oauth/callback to callbackURL when you call signIn.social
Samy
SamyOP2mo ago
but then there is not state in the callback url:
app.get("/oauth/callback", (req, res) => {
const queryParams = new URLSearchParams(req.query).toString();

const newUrl = `${GOOGLE_CALLBACK_URL}?${queryParams}`;
console.log("Redirecting to:", newUrl);

mainWindow.loadURL(newUrl);

res.send("Redirecting...");
});
app.get("/oauth/callback", (req, res) => {
const queryParams = new URLSearchParams(req.query).toString();

const newUrl = `${GOOGLE_CALLBACK_URL}?${queryParams}`;
console.log("Redirecting to:", newUrl);

mainWindow.loadURL(newUrl);

res.send("Redirecting...");
});
2025-03-27T09:51:21.255Z ERROR [Better Auth]: State not found undefined it redirects to to http://localhost:3939/oauth/callback but with the data or state with it
bekacru
bekacru2mo ago
calling signIn.social should return you a url in the response.
Samy
SamyOP2mo ago
sorry, I don't understand what you meant. this is how im doing it
const currentUrl = generateUrl();

const callbackURL =
typeof window !== "undefined" && window.electron
? "http://localhost:3939/oauth/callback"
: currentUrl;

const { data: userData } = await client.signIn.social(
{
provider,
callbackURL,
},
{
onRequest: () => {
setIsLoading(true);
sendGTMEvent({
event: "Provider Sign-in",
method: provider,
from: "Dialog",
});
},
onSuccess: () => {
setIsLoading(false);
onOpenChange(false);
},
onFailure: () => {
setIsLoading(false);
toast.error("Sign-In failed!", {
description: `Failed to sign in with ${provider}`,
});
sendGTMEvent({
event: "Provider Sign-in Error",
method: provider,
from: "Dialog",
error: "Failed to sign in",
});
},
}
);
const currentUrl = generateUrl();

const callbackURL =
typeof window !== "undefined" && window.electron
? "http://localhost:3939/oauth/callback"
: currentUrl;

const { data: userData } = await client.signIn.social(
{
provider,
callbackURL,
},
{
onRequest: () => {
setIsLoading(true);
sendGTMEvent({
event: "Provider Sign-in",
method: provider,
from: "Dialog",
});
},
onSuccess: () => {
setIsLoading(false);
onOpenChange(false);
},
onFailure: () => {
setIsLoading(false);
toast.error("Sign-In failed!", {
description: `Failed to sign in with ${provider}`,
});
sendGTMEvent({
event: "Provider Sign-in Error",
method: provider,
from: "Dialog",
error: "Failed to sign in",
});
},
}
);
my app works like, if accounts.google.com opens in the app, it opens the url in the users browser where they have their accounts, after they select their account they redirects to http://localhost:3939/oauth/callback that is a server created from the electron app, and when user redirects to this url, the app opens the api route ${DOMAIN}/api/auth/callback/google for signiin with the data is there any way to get the session data from the site?

Did you find this page helpful?