Issue with getKindeServerSession().refreshTokens(); in Next.js App Router

I am currently integrating Kinde with a Next.js application using the App Router. In my application, when a user logs in and successfully completes a payment transaction, I would like to set new properties for the user as paid user. However, I am encountering an issue when attempting to refresh the ID token using the method getKindeServerSession().refreshTokens();. It seems I am unable to fetch a new ID token after updating the user's properties. Could you please provide guidance on how to resolve this issue or recommend an alternative approach for refreshing the ID token in this context? Thank you!
19 Replies
onderay
onderay2mo ago
@Abel Trần sorry that you are seeing this issue. What version of the Next.js SDK are you using? When you say you are unable to fetch a new ID token, are you getting an error or is the token coming back un updated?
Abel Trần
Abel TrầnOP2mo ago
@Andre @ Kinde FYI, I am using: "next": "14.2.4", "@kinde-oss/kinde-auth-nextjs": "^2.3.8" I don't see any error when I use await getKindeServerSession().refreshTokens();, but the token does not change.
onderay
onderay2mo ago
Thanks for the details. Able to update to v2.3.10?
Abel Trần
Abel TrầnOP2mo ago
When I update to v2.3.10, await getKindeServerSession().refreshTokens(); takes a long time to refresh, but the ID Token does not update.
onderay
onderay2mo ago
Ok, thanks, I have passed this along to the team
Abel Trần
Abel TrầnOP2mo ago
Thank you! Please let me know if there's any further information or assistance I can provide to help with the investigation.
leo_kinde
leo_kinde2mo ago
Hi @Abel Trần , just to confirm, these are user properties added to the id token through token customization, then updated via API? Let me look into whether we should automatically invalid the cache in this case, in the mean time you can try making a call via the Management API to refresh the claims first using this API method: https://kinde.com/api/docs/#refresh-user-claims-and-invalidate-cache
Abel Trần
Abel TrầnOP2mo ago
I updated the user properties via API. After that, I tried calling the refresh token and even refreshing the user claims, but the token hasn't changed.
Abel Trần
Abel TrầnOP2mo ago
Here is the my sample code
No description
leo_kinde
leo_kinde2mo ago
Hi @Abel Trần , It looks like the cache should be updated automatically, so you shouldn't need to call the refresh_claims endpoint. After updating the properties via API, you can then call refreshTokens() to get the updated tokens. Here is the code I used:
const { getUser, refreshTokens } = getKindeServerSession();

const userBefore = await getUser();
console.log("user properties before", userBefore.properties);

init();
const res = await Users.updateUserProperty({
propertyKey: "userprop",
userId: userBefore.id,
value: "new value",
});
console.log("update response", res);

const newTokens = await refreshTokens();
console.log("updated tokens", newTokens);

const userAfter = await getUser();
console.log("user properties after", userAfter.properties);
const { getUser, refreshTokens } = getKindeServerSession();

const userBefore = await getUser();
console.log("user properties before", userBefore.properties);

init();
const res = await Users.updateUserProperty({
propertyKey: "userprop",
userId: userBefore.id,
value: "new value",
});
console.log("update response", res);

const newTokens = await refreshTokens();
console.log("updated tokens", newTokens);

const userAfter = await getUser();
console.log("user properties after", userAfter.properties);
Abel Trần
Abel TrầnOP2mo ago
@leo_kinde I tried refreshTokens() but my token does not change. What can I do next?
Abel Trần
Abel TrầnOP2mo ago
@Andre @ Kinde @leo_kinde Can you help me check this again? I successfully updated the value, but I cannot refresh to get the new values or token. If I log out and log in again, I will receive the new value / token.
No description
No description
No description
leo_kinde
leo_kinde2mo ago
@Abel Trần , the null response from refreshTokens() looks like there might be some error happening as it should return the new tokens. Can you set the environment variable KINDE_DEBUG_MODE to true and run it again and have a look to see if there are any errors logged?
Abel Trần
Abel TrầnOP2mo ago
The refresh token is null when I use it in the middleware. However, when I use the server action, I can see the token, but it’s still the old one. I manually try to update test_kinde_prop in Kinde, but it seems undefined.
No description
No description
No description
Oli - Kinde
Oli - Kinde2mo ago
Hey @Abel Trần, Apologies for not getting back to you sooner. We are still looking into this issue. I update you, more regularly, as we progress in fixing this issue.
Abel Trần
Abel TrầnOP2mo ago
I updated to v2.3.11. It works well when I update properties via the API, but if I update them directly on the Kinde Dashboard, the data does not refresh.
Oli - Kinde
Oli - Kinde2mo ago
Hey @Abel Trần, This does not sound like the expected behaviour. I have let my team know this too. Please continue to let us know of any other issues/findings you come across.
Abel Trần
Abel TrầnOP2mo ago
Yes, I will
Peteswah
Peteswah2mo ago
Hey Abel what is the behaviour you're expecting on your app when data is updated on the Kinde dashboard? I will try and recreate the server action experience you are having today
'use client';

import {useKindeBrowserClient} from '@kinde-oss/kinde-auth-nextjs';
import {updateUserName} from '../../actions/kinde';

export const PersonData = () => {
const {user} = useKindeBrowserClient();
const handleSubmit = async (formData: FormData) => {
const givenName = formData.get('givenName') as string;
await updateUserName({userId: user.id, userName: givenName});
// window.location.reload(); (if using browser client)
};
return (
<div>
<form action={handleSubmit}>
<label htmlFor="orgName">Organization Name:</label>
<input
type="text"
id="givenName"
name="givenName"
defaultValue={user?.given_name}
/>
<button type="submit">Update user first name</button>
</form>
<pre>{JSON.stringify(user, null, 2)}</pre>;
</div>
);
};
'use client';

import {useKindeBrowserClient} from '@kinde-oss/kinde-auth-nextjs';
import {updateUserName} from '../../actions/kinde';

export const PersonData = () => {
const {user} = useKindeBrowserClient();
const handleSubmit = async (formData: FormData) => {
const givenName = formData.get('givenName') as string;
await updateUserName({userId: user.id, userName: givenName});
// window.location.reload(); (if using browser client)
};
return (
<div>
<form action={handleSubmit}>
<label htmlFor="orgName">Organization Name:</label>
<input
type="text"
id="givenName"
name="givenName"
defaultValue={user?.given_name}
/>
<button type="submit">Update user first name</button>
</form>
<pre>{JSON.stringify(user, null, 2)}</pre>;
</div>
);
};
export const updateUserName = async (props: {
userId: string;
userName: string;
}) => {
init();
await Users.updateUser({
id: props.userId,
requestBody: {
given_name: props.userName
}
});

await getKindeServerSession().refreshTokens();
revalidatePath('/dashboard', 'page');
};
export const updateUserName = async (props: {
userId: string;
userName: string;
}) => {
init();
await Users.updateUser({
id: props.userId,
requestBody: {
given_name: props.userName
}
});

await getKindeServerSession().refreshTokens();
revalidatePath('/dashboard', 'page');
};
^ this is how to use refreshtoken in the server action to get the user to update with the API To see the updated user data, it will work automatically if you grab them from getKindeServerSession, but will need to force a reload (window.location.reload) for browserclient
Want results from more Discord servers?
Add your server