I redirect to the login page after my access token expires.

Hello, I am redirected to the login page every time my access token expires. It does not refresh automatically. Below, I am sharing my token settings screenshot. What am I missing here? i am using next js.
No description
No description
15 Replies
Rasel Hossain
Rasel HossainOP2mo ago
I want to automatically refresh the access token behind the scenes, so users are not repeatedly redirected to the login page. My access token expires in one day. Could you please share some resources or documents about the implementation?
Rasel Hossain
Rasel HossainOP2mo ago
i am using
"@kinde-oss/kinde-auth-nextjs": "^2.1.15"
"@kinde-oss/kinde-auth-nextjs": "^2.1.15"
but it's says that "Property 'refreshTokens' does not exist"
No description
Claire_Kinde
Claire_Kinde5w ago
Hi Rasel, are you using a custom domain? Using a custom domain allow for persistent authentication states because we can then support secure first-party cookies. Without a custom domain, this will probably persist. https://docs.kinde.com/build/domains/pointing-your-domain/?r=search#_top
Rasel Hossain
Rasel HossainOP5w ago
yes, i am using a custom domain for my production environment.
No description
Rasel Hossain
Rasel HossainOP5w ago
Hello @Claire_Kinde after updating the Kinde npm version, I received the refreshTokens property from the getKindeServerSession(). However, I am facing a window refreshing issue. Below, I am writing the details about it. We're using Kinde as the authentication provider in our application, which includes a quiz feature where users are not allowed to reload their tab during the quiz to prevent cheating. We are currently facing an issue with the refresh token. I've limited the access token to 5 minutes in the Kinde admin dashboard. On the server side, I'm using the following code to refresh tokens:
const { refreshTokens } = await getKindeServerSession();
await refreshTokens();
const { refreshTokens } = await getKindeServerSession();
await refreshTokens();
On the client side, I am using the following code:
const { getToken } = useKindeBrowserClient();
getToken();
const { getToken } = useKindeBrowserClient();
getToken();
We are using the latest Next.js SDK from Kinde. As mentioned earlier, when the quiz starts, users are not allowed to reload the window. If the window is reloaded, it could result in cheating, which we want to prevent. However, when refreshTokens() or getToken() is invoked, the page reloads to refresh the access token. Our requirement is to refresh the access token silently in the background without reloading the page. We haven’t been able to find a solution to this issue yet. Could you please guide us on how to handle this scenario with Kinde?
Claire_Kinde
Claire_Kinde5w ago
@Rasel Hossain I'm referring to someone else in the team to see if they can help.
Peteswah
Peteswah5w ago
Hey @Rasel Hossain, would you be able to try wrapping your app in a Kinde Provider?
// AuthProvider.tsx
'use client';
import {KindeProvider} from '@kinde-oss/kinde-auth-nextjs';

export const AuthProvider = ({children}) => {
return <KindeProvider>{children}</KindeProvider>;
};
// AuthProvider.tsx
'use client';
import {KindeProvider} from '@kinde-oss/kinde-auth-nextjs';

export const AuthProvider = ({children}) => {
return <KindeProvider>{children}</KindeProvider>;
};
// layout.tsx
...
import {AuthProvider} from './AuthProvider';

export const metadata = {
title: 'Kinde Auth',
description: 'Kinde with NextJS App Router'
};

export default async function RootLayout({
children
}: {
children: React.ReactNode;
}) {
return (
<AuthProvider>
<html lang="en">
// Your app code here
</html>
</AuthProvider>
);
}
// layout.tsx
...
import {AuthProvider} from './AuthProvider';

export const metadata = {
title: 'Kinde Auth',
description: 'Kinde with NextJS App Router'
};

export default async function RootLayout({
children
}: {
children: React.ReactNode;
}) {
return (
<AuthProvider>
<html lang="en">
// Your app code here
</html>
</AuthProvider>
);
}
This should refresh tokens in he background
Rasel Hossain
Rasel HossainOP5w ago
Hay @Peter (Kinde) . I've implemented it as you suggested, but I forgot to mention that I'm using TRPC for the API. Do I need to make any changes to the TRPC context? Below is a sample of my TRPC context and Protected procedure, as I'm encountering an error saying 'User is not authenticated' from the protected procedure
export const createTRPCContext = async () => {
const { isAuthenticated } = getKindeServerSession();
const isUserAuthenticated = await isAuthenticated();

// If user is not authenticated, return null session
if (!isUserAuthenticated) {
return {
db: DBClient,
session: null,
isAuthenticated: false,
};
}

const session = await getUserSession();

return {
session,
db: DBClient,
isAuthenticated: true,
};
};

export type TRPCContext = typeof createTRPCContext;
export const createTRPCContext = async () => {
const { isAuthenticated } = getKindeServerSession();
const isUserAuthenticated = await isAuthenticated();

// If user is not authenticated, return null session
if (!isUserAuthenticated) {
return {
db: DBClient,
session: null,
isAuthenticated: false,
};
}

const session = await getUserSession();

return {
session,
db: DBClient,
isAuthenticated: true,
};
};

export type TRPCContext = typeof createTRPCContext;
Protected Procedure :
// Protected Procedure
export const protectedProcedure = t.procedure.use(async ({ ctx, next }) => {
const isAuthenticated = ctx.isAuthenticated;
if (!isAuthenticated || ctx.session === null) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "User is not authenticated",
});
}

const session = ctx.session;


return next({
ctx: {
...ctx,
session,
},
});
});
// Protected Procedure
export const protectedProcedure = t.procedure.use(async ({ ctx, next }) => {
const isAuthenticated = ctx.isAuthenticated;
if (!isAuthenticated || ctx.session === null) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "User is not authenticated",
});
}

const session = ctx.session;


return next({
ctx: {
...ctx,
session,
},
});
});
Hay @Peter (Kinde) it does not work
Claire_Kinde
Claire_Kinde4w ago
Hi Rasel. The team just came online now. I'll follow up for you. Hi Rasel. Due to really high support demands, Peter was unable to get to this today. Apologies. We have far less people available on weekends, but it might be picked up. Otherwise, Monday.
Rasel Hossain
Rasel HossainOP4w ago
no problem @Claire_Kinde . take your time
Claire_Kinde
Claire_Kinde4w ago
Hi @Rasel Hossain . Nudging the team on this 🙂
Peteswah
Peteswah4w ago
Hey @Rasel Hossain , I haven't used TRPC before, but it looks like what you are doing there is correct. refreshing the tokens in the background should be happening when you call isAuthenticated from the TRPCContext. The reason it may be redirecting to Kinde login could be middleware. Are you using Kinde middleware?
Rasel Hossain
Rasel HossainOP4w ago
are you talking about withAuth(req). we are not using it.
Peteswah
Peteswah3w ago
Hey @Rasel Hossain , I thought the KindeProvider might be the solution to your problem, but it looks like a refresh is necessary to get the refreshToken to work properly. This is an issue we're looking to address asap - then hopefully we can get the token refreshing in the background
Rasel Hossain
Rasel HossainOP3w ago
ok @Peteswah
Want results from more Discord servers?
Add your server