feat(nextauth): properly handle signout
When signing out, by default keycloak session is not terminated, this fixes it and sends a request to keycloak instance to terminate the keycloak session.
This commit is contained in:
parent
2a7b833b2e
commit
377e9e9570
1 changed files with 43 additions and 0 deletions
|
|
@ -6,6 +6,9 @@ import {
|
|||
type DefaultSession,
|
||||
} from "next-auth";
|
||||
import KeycloakProvider from "next-auth/providers/keycloak";
|
||||
import { type KeycloakProfile } from "next-auth/providers/keycloak";
|
||||
import { type JWT } from "next-auth/jwt";
|
||||
import { type OAuthConfig } from "next-auth/providers";
|
||||
import { env } from "~/env.mjs";
|
||||
import { prisma } from "~/server/db";
|
||||
|
||||
|
|
@ -30,6 +33,18 @@ declare module "next-auth" {
|
|||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the Keycloak fix/workaround, see code bellow for method `signOut`.
|
||||
*
|
||||
* @see https://stackoverflow.com/a/75526977
|
||||
*/
|
||||
declare module 'next-auth/jwt' {
|
||||
interface JWT {
|
||||
id_token?: string;
|
||||
provider?: string;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for NextAuth.js used to configure adapters, providers, callbacks, etc.
|
||||
*
|
||||
|
|
@ -46,6 +61,18 @@ export const authOptions: NextAuthOptions = {
|
|||
image: user.image,
|
||||
},
|
||||
}),
|
||||
/**
|
||||
* Part of the Keycloak fix/workaround, see code bellow for method `signOut`.
|
||||
*
|
||||
* @see https://stackoverflow.com/a/75526977
|
||||
*/
|
||||
async jwt({ token, account }) {
|
||||
if (account) {
|
||||
token.id_token = account.id_token
|
||||
token.provider = account.provider
|
||||
}
|
||||
return token
|
||||
},
|
||||
},
|
||||
adapter: PrismaAdapter(prisma),
|
||||
providers: [
|
||||
|
|
@ -68,6 +95,22 @@ export const authOptions: NextAuthOptions = {
|
|||
* @see https://next-auth.js.org/providers/github
|
||||
*/
|
||||
],
|
||||
events: {
|
||||
/**
|
||||
* Fix for Keycloak not destroying the session token on logout,
|
||||
* we must send an extra request to delete the session.
|
||||
*
|
||||
* @see https://stackoverflow.com/a/75526977
|
||||
*/
|
||||
async signOut({ token }: { token: JWT }) {
|
||||
if (token.provider === "keycloak") {
|
||||
const issuerUrl = (authOptions.providers.find(p => p.id === "keycloak") as OAuthConfig<KeycloakProfile>).options!.issuer!
|
||||
const logOutUrl = new URL(`${issuerUrl}/protocol/openid-connect/logout`)
|
||||
logOutUrl.searchParams.set("id_token_hint", token.id_token!)
|
||||
await fetch(logOutUrl);
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Reference in a new issue