K
Kindeβ€’10mo ago
DJKnaeckebrot

Post Logout Redirect Parameter

Hi there! I am using Next 13.4.19 with "@kinde-oss/kinde-auth-nextjs": "^2.1.10" I am trying to change the post logout URL for a single page. I have tried /api/auth/logout?post_logout_redirect_url=/logout?from=logout but this keept sending me to / which is my default after logout url. I even tried making it with the logout link
import {
LogoutLink
} from "@kinde-oss/kinde-auth-nextjs/components";
...
return (
<>
<LogoutLink postLogoutRedirectURL={"/logout?from=logout"}>
Text
</LogoutLink>
</>
);
import {
LogoutLink
} from "@kinde-oss/kinde-auth-nextjs/components";
...
return (
<>
<LogoutLink postLogoutRedirectURL={"/logout?from=logout"}>
Text
</LogoutLink>
</>
);
But this also sends me back to / This is intended or am I experiencing some bug or just made a mistake in the config? Thanks for your help! πŸ™‚
47 Replies
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
Not that it helps much , but I was also able to reproduce this just now. I also noticed that on the type definition for LogoutLink, the postLogoutRedirectURL exists but it's not mentioned anywhere in the SDK docs
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
Was wondering the same. I saw it in the types but it seems it won't do it.
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
GitHub
kinde-auth-nextjs/src/components/LogoutLink.js at 059547d6b6eb88b80...
Kinde NextJS SDK - authentication for server rendered apps - kinde-oss/kinde-auth-nextjs
GitHub
kinde-auth-nextjs/src/components/RegisterLink.js at 059547d6b6eb88b...
Kinde NextJS SDK - authentication for server rendered apps - kinde-oss/kinde-auth-nextjs
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
Obviously I haven't tested anything, I can potentially do a build and play around with it tomorrow, see if my theory is correct
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
Thank you so much!
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
(Assuming the Kinde guys don't get to it before I do) Could be fun to contribute a PR though 🀷
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
I might take this old code and replace it in my node_modules and see if it works
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
Let me know how it goes
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
It seems that the URL passing is fine as is. I think the handling seems to be more the issue. I have the feeling my app crashes and resets to / after /api/auth/logout is called with params. I'll see if I get any further but help from the Kinde guys would be much appretiated
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
wdym by handling?
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
I can see that it adds the parameter to the url but i haven’t found out where this logic is getting processed so where the actual redirect happens. For me it seems that the issue might be there
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
Hm weird, I haven't been able to test today yet (at work). If there's no other news by the time I get home I might have a quick look for fun You had any luck with this at all? I've been digging through the sdk source code for like an hour and can't find anything I can see that it's broken, I just can't find how
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
No unfortunately not. Im currently following a "hint" that in the SessionManger it only has the post login url as cookie but not the post logout url https://github.com/kinde-oss/kinde-auth-nextjs/blob/059547d6b6eb88b808aab04c653a380ecdb30ab3/src/session/sessionManager.js#L23 I will check if adding the post logout url will change anything otherwise the kinde guys need to have a view
GitHub
kinde-auth-nextjs/src/session/sessionManager.js at 059547d6b6eb88b8...
Kinde NextJS SDK - authentication for server rendered apps - kinde-oss/kinde-auth-nextjs
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
Yes I saw that too! I've added that and it hasn't changed anything for me
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
yep same for me 😦
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
I think that's part of the story but not the whole story
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
yeah guess I'll need to wait for one of the kinde guys to have a look. I'lL might do some more digging but I am kinda stuck rn πŸ˜„ Thanks for your help so far tho, much appretiated!
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
I can see that adding this into the sessionmanager it gets added to the cookies but seems like its not getting used somehow
No description
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
Yeah I've been trying to see where the login redirect actually picks up the cookie but I'm not finding it unfortunately actually, I think it may have to do with src/handlers/callback.js This is where the post_login_redirect_url is being used to redirect to the specified url, logout doesn't have an equivalent
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
oh yeah, but I am not too sure if you get back to the callback on logout
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
You don't (and probably shouldn't)
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
I think this is odd... /src/authMiddleware/authMiddleware.js line 9
No description
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
this basically always uses my set default logout url and not the one provided in the URL if I understood it right
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
Tbh, I don't think this ever worked
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
Suddenly, it all makes sense @DJKnaeckebrot
No description
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
πŸ˜‚
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
hahaha lol!
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
He's testing in prod fr Oh, he's in the discord server, maybe we can ask him directly Hi @dc, would you be able to give us a hand with this? We can't seem to get it to work
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
Little Update: I have checked the typescipt SDK as this gets referenced: types.d.ts:
..
register: (
sessionManager: SessionManager,
options?: RegisterURLOptions
) => Promise<URL>;
getUser: (sessionManager: SessionManager) => Promise<UserType>;
logout: (sessionManager: SessionManager) => Promise<URL>;
login: (
sessionManager: SessionManager,
options?: LoginURLOptions
) => Promise<URL>;
..
..
register: (
sessionManager: SessionManager,
options?: RegisterURLOptions
) => Promise<URL>;
getUser: (sessionManager: SessionManager) => Promise<UserType>;
logout: (sessionManager: SessionManager) => Promise<URL>;
login: (
sessionManager: SessionManager,
options?: LoginURLOptions
) => Promise<URL>;
..
Seems as if for the types the options are missing. Checking the src/routerClients/AppRouterClient.js it references the typescript SDK with the this.kindeClient call:
import {createKindeServerClient} from '@kinde-oss/kinde-typescript-sdk';

..
this.kindeClient = createKindeServerClient(
config.grantType,
config.clientOptions
);
import {createKindeServerClient} from '@kinde-oss/kinde-typescript-sdk';

..
this.kindeClient = createKindeServerClient(
config.grantType,
config.clientOptions
);
While the src/handlers/logout.js call sets up the authURL by using:
const authUrl = await routerClient.kindeClient.logout(
routerClient.sessionManager,
{
authUrlParams: Object.fromEntries(routerClient.searchParams),
}
);
const authUrl = await routerClient.kindeClient.logout(
routerClient.sessionManager,
{
authUrlParams: Object.fromEntries(routerClient.searchParams),
}
);
Console logging the authUrl leads to : https://identity.teamsynix.org/logout?redirect=http://localhost:3000/login while authUrlParams: Object.fromEntries(routerClient.searchParams) returns : {"post_logout_redirect_url":"/login?type=bewerben"} Tbh I dont rly know if this error is within the typescript SDK or the NextJS SDK..
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
I found that as well I tried making a type for it in the next.js sdk and nothing happened still unfortunately It is a tricky issue @DJKnaeckebrot are we dumb? well I know I am...
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
Did you set your url in here?
No description
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
If this was the issue all along... big facepalm.. @Andre @ Kinde has been watching us all this time laughing
dave_kinde
dave_kindeβ€’10mo ago
Haha, sadly not the issue in this case, and definitely not dumb! Thanks for raising this one @Joel @DJKnaeckebrot and sorry it's taken me so long to get to it. I'll just provide some context There is the .env variable KINDE_POST_LOGOUT_REDIRECT_URL this typically is the one that you would have mapped in the Kinde admin area in the Allowed logout redirect urls - if it isn't mapped there then it will fall back to a default Kinde log out screen. There is then the argument to <LogoutLink /> which is post_logout_redirect_url the idea of this one is to be able to provide dynamic logout URLs that differ from the default. The idea was that this way you could add a single logout url to the allow list (as it could be a headache to add every conceivable url) and then forward the user onwards on return to your application. (This is the same way the post_login_redirect_url argument works for logging in - typically that is used to remember where they were trying to visit). With the LoginLink argument the param is stored in the NextJS SessionManager - essentially just a cookie which can be accessed when you are redirected back from Kinde. One approach you could use (I should add a caveat here that I am not a NextJS expert by any means) is having a global logout route (could also be middleware I expect) something like: .env
KINDE_POST_LOGOUT_REDIRECT_URL=http://localhost:3000/api/logout
KINDE_POST_LOGOUT_REDIRECT_URL=http://localhost:3000/api/logout
^ this should also be added in Allowed logout redirect URLs /api/logout
import { cookies } from "next/headers";
import { NextRequest, NextResponse } from "next/server";

export async function GET(request) {
const cookieJar = cookies();

const path = cookieJar.get("post_logout_redirect_url").value;

return NextResponse.redirect(new URL(path, request.url));
}
import { cookies } from "next/headers";
import { NextRequest, NextResponse } from "next/server";

export async function GET(request) {
const cookieJar = cookies();

const path = cookieJar.get("post_logout_redirect_url").value;

return NextResponse.redirect(new URL(path, request.url));
}
The /api/logout is then able to handle any values passed to <LogoutLink post_logout_redirect_url="/some-where-else" />
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
Hey thanks for the detailed response Dave! So if I understand correctly, we are supposed to handle the post login redirect ourselves in this case?
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
Yeah i set those urls πŸ˜„ Was the first thing I checked haha as I initially was landing on the kinde default page so I added all pages and even with the searchParams in the URL πŸ˜„ Thanks for this detailed response! I'll try to get this implemented and will let you know! Eitherway I am just wondering if this SDK still should be able to do this without making this "workaround" with the custom logout page? If so I might can try to dig deeper on why it wont pass/use the param πŸ™‚ I had to add the KINDE_SITE_URL as I use a reverse proxy and the provided code was putting localhost:4001 instead of my domain πŸ˜„ Otherwise its working now! For reference if anyone ever needs it I'll leave the code for the /api/logout/ route
import { cookies } from "next/headers";
import { NextRequest, NextResponse } from "next/server";

export async function GET(request: NextRequest) {
const cookieJar = cookies();

// @ts-ignore
let path = cookieJar.get("post_logout_redirect_url").value;

// Get the domain from environment variable
const siteURL = process.env.KINDE_SITE_URL;

// Ensure siteURL is not empty and path is not an absolute URL
if (siteURL && !path.startsWith("http")) {
// Prepend domain to the path
path = siteURL + path;
}

return NextResponse.redirect(new URL(path, request.url));
}
import { cookies } from "next/headers";
import { NextRequest, NextResponse } from "next/server";

export async function GET(request: NextRequest) {
const cookieJar = cookies();

// @ts-ignore
let path = cookieJar.get("post_logout_redirect_url").value;

// Get the domain from environment variable
const siteURL = process.env.KINDE_SITE_URL;

// Ensure siteURL is not empty and path is not an absolute URL
if (siteURL && !path.startsWith("http")) {
// Prepend domain to the path
path = siteURL + path;
}

return NextResponse.redirect(new URL(path, request.url));
}
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
Since its a bit counter-intuitive that this is the case, is it possible for this behaviour to be documented as part of the sdk docs?
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
+1
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
Glad you got it working though dj
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
thanks for your help to both of you!
dave_kinde
dave_kindeβ€’10mo ago
Eitherway I am just wondering if this SDK still should be able to do this without making this "workaround" with the custom logout page? If so I might can try to dig deeper on why it wont pass/use the param πŸ™‚
I did wonder this myself. There are 3 ways of handling the param that I can think of 1. The param override to the .env variable setting, so it would get passed to Kinde and we redirect straight to it. This would mean the dynamic URL would need to exist in Allowed logout redirect URLs in the admin area This seems to be both of your expected behaviour. I like that there is no additional code needed but this would mean the behaviour was different to the post_login_redirect_url param which could be confusing. Also could mean a lot of URLs having to be added to the allow list 2. As it is now, the .env variable is used for the initial logout redirect and the param is stored in the Session Manager and can be used in a custom logout page set up by the founder. I like that this gives flexibility to the dev, possibly just documentation thing, although more setup needed than the above 3. Similar to 2, except we provide an additional api/auth/post-logout handler within the SDK that essentially provides the code snippet above for you. So in theory you can then just add api/auth/post-logout to the Allowed Logout Callback URls - this seems like a nice hybrid solution Would love to hear your thoughts
DJKnaeckebrot
DJKnaeckebrotOPβ€’10mo ago
I like the 3. solution as it seems to be the best of both worlds πŸ™‚ Hey @Dave - Kinde sorry for the ping. I have made some changes to the SDK so it adds the /api/auth/postlogout functionallity. I was just wondering if this looks good to you guys before I open the PR
import RouterClient from '../routerClients/RouterClient';
import {config} from '../config/index';

/**
*
* @param {RouterClient} routerClient
*/

export const postlogout = async (routerClient) => {
const postLogoutRedirectURL = routerClient.sessionManager.getSessionItem(
'post_logout_redirect_url'
);

let redirectURL;

if (config.redirectURL + postLogoutRedirectURL === config.postLogoutRedirectURL || postLogoutRedirectURL === null) {
redirectURL = config.postLogoutRedirectURL;
} else if (!postLogoutRedirectURL.startsWith("http") && !postLogoutRedirectURL.startsWith("https")) {
redirectURL = config.redirectURL + postLogoutRedirectURL;
}

await routerClient.sessionManager.removeSessionItem('post_logout_redirect_url');

routerClient.redirect(redirectURL);
};
import RouterClient from '../routerClients/RouterClient';
import {config} from '../config/index';

/**
*
* @param {RouterClient} routerClient
*/

export const postlogout = async (routerClient) => {
const postLogoutRedirectURL = routerClient.sessionManager.getSessionItem(
'post_logout_redirect_url'
);

let redirectURL;

if (config.redirectURL + postLogoutRedirectURL === config.postLogoutRedirectURL || postLogoutRedirectURL === null) {
redirectURL = config.postLogoutRedirectURL;
} else if (!postLogoutRedirectURL.startsWith("http") && !postLogoutRedirectURL.startsWith("https")) {
redirectURL = config.redirectURL + postLogoutRedirectURL;
}

await routerClient.sessionManager.removeSessionItem('post_logout_redirect_url');

routerClient.redirect(redirectURL);
};
I added a remove of the sessionItem before the redirect cause otherwise if you only use logout it will keep using that cookie (atleast for me) πŸ˜„ I just saw I might can add another check in the else if for the url not being null tho
Daniel_Kinde
Daniel_Kindeβ€’10mo ago
Thanks for this @DJKnaeckebrot , best thing to do it open the PR to get eyes on it
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
How possible is it to use the same callback route that the login callback uses for logout? ie check whether the user is logging in or logging out and redirect accordingly from the same endpoint
dave_kinde
dave_kindeβ€’10mo ago
It's definitely possible but I do prefer the separation of concerns. The callback for login contains a fair bit of logic that isn't relevant for logging out
MALEV0L3NT
MALEV0L3NTβ€’10mo ago
That makes sense, I think either option 2 or 3 makes sense in that case. Option 3 seems like it would behave most similarly to the login redirection and would probably alleviate the most confusion. Is it useful for the developer to have control over this behaviour @Dave - Kinde? I can't think of many circumstances where custom behaviour would be needed (option 2) but you're obviously more knowledgable than I am here
Want results from more Discord servers?
Add your server