Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getServerToken returns null if header size exceeds default size #160

Open
mpgalaxy opened this issue Jan 25, 2024 · 0 comments
Open

getServerToken returns null if header size exceeds default size #160

mpgalaxy opened this issue Jan 25, 2024 · 0 comments

Comments

@mpgalaxy
Copy link

mpgalaxy commented Jan 25, 2024

Environment

  • Nuxt 3.8.0 in dev mode
  • Node 18.18.2
  • Apollo graphql backend
  • @auth/core: 0.17.0 (due to this bug)
  • authjs-nuxt: 0.3.5
  • Using KeycloakProvider with local Keycloak 19 (quarkus) via docker on localhost

Reproduction

Due to mandatory keycloak reproduction is not possible, you have to set up a local keycloak with realm, public client and many client roles to be added to a test user.

Describe the bug

Due to my token endpoint ( /api/token ) for graphql I need the access_token of keycloak in my token, so I added it in the jwt callback. if I don't add the access_token in the jwt callback it also isn't present in getServerToken.

If the header is small because the user doesn't have many client roles assigned everything works fine, getServerToken returns the token as expected, but If I add more client roles resulting in a header larger than the default size or add the refresh_token to the token (which I need for other purposes) the getServerToken returns null, no error message given.

On the client side everything is fine.
If I add both tokens to the session via the session callback the tokens are present.

This is my /server/api/auth/[...].ts :

import { NuxtAuthHandler } from "#auth";
import KeycloakProvider from "@auth/core/providers/keycloak"
import type { AuthConfig } from "@auth/core/types"
import { jwtDecode } from "jwt-decode";

const runtimeConfig = useRuntimeConfig()

async function getMyRoles(token: string) {
    const decodedToken = await jwtDecode(token)
    if (decodedToken.resource_access["mytestclient"].roles) {
        return decodedToken.resource_access["mytestclient"].roles
    } else {
        return []
    }
}

export const authOptions: AuthConfig = {
    secret: "1234",  <- dummy entry (derived from sidebase), this is a public client
    providers: [
        KeycloakProvider({
            clientId: "mytestclient,
            clientSecret: "1234",  <- dummy entry (derived from sidebase), this is a public client
            issuer: "http://localhost:8080/realms/testrealm",
        })
    ],
    callbacks: {
        async jwt({ token, account, user, trigger, session }) {
            if (token && user && account && account.access_token && trigger === "signIn") {
                token.access_token = account.access_token;
                token.refresh_token = account.refresh_token;
                return Promise.resolve(token);
            }

            if (token && trigger === undefined) {
                return Promise.resolve(token);
            }
            return Promise.resolve(token);
        },
        async session({ session, token, user }) {
            const tokenRoles = await getMyRoles(token.access_token)
            session.roles = tokenRoles
            session.token = token
            return Promise.resolve(session)
        }
    }
}

// @ts-ignore
export default NuxtAuthHandler(authOptions, runtimeConfig)

And this is my /server/api/token.get.ts :

import { authOptions } from "./auth/[...]"
import { getServerSession, getServerToken } from "#auth"

export default defineEventHandler(async (event) => {
    const session = await getServerSession(event, authOptions)
    const token = await getServerToken(event, authOptions) <- this returns null if header size is larger than the default size
    console.log('SERVER TOKEN::')
    console.log(token)
    return { loggedIn: true, token: token, session: session }    
})

With a large access_token or the refresh_token present (=>large header size) I get this:

console.log('SERVER TOKEN::')
console.log(token)
=> 
SERVER TOKEN::
null

I'm not sure if this is an issue of @auth/core 0.17.0 or the current version of this module, but this bug is present making the lib unusable on server side for us. In our application users can have many client roles and composite client roles (which is also working perfectly fine with nuxt2 and the auth module from nuxt), thus reducing the client roles is not an option.
This is clearly a bug. ;)

Additional context

async session({ session, token, user }) {
     const tokenRoles = await getMyRoles(token.access_token)
     session.roles = tokenRoles
     session.token = token <= this is a workaround to access the token via getServerSession on server side,
                              but no solution for this bug ;)
     return Promise.resolve(session)
}

Logs

see description of the bug
@mpgalaxy mpgalaxy changed the title getServerToken returns null if headers size exceeds default size getServerToken returns null if header size exceeds default size Jan 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant