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,
|
type DefaultSession,
|
||||||
} from "next-auth";
|
} from "next-auth";
|
||||||
import KeycloakProvider from "next-auth/providers/keycloak";
|
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 { env } from "~/env.mjs";
|
||||||
import { prisma } from "~/server/db";
|
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.
|
* Options for NextAuth.js used to configure adapters, providers, callbacks, etc.
|
||||||
*
|
*
|
||||||
|
|
@ -46,6 +61,18 @@ export const authOptions: NextAuthOptions = {
|
||||||
image: user.image,
|
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),
|
adapter: PrismaAdapter(prisma),
|
||||||
providers: [
|
providers: [
|
||||||
|
|
@ -68,6 +95,22 @@ export const authOptions: NextAuthOptions = {
|
||||||
* @see https://next-auth.js.org/providers/github
|
* @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