[GH-ISSUE #1328] Is there a way to include organization data in the JWT? #8694

Closed
opened 2026-04-13 03:51:22 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @winstonpurnomo on GitHub (Feb 1, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/1328

In this code:

export const auth = betterAuth({
  database: drizzleAdapter(db, {
    provider: "pg",
  }),
  plugins: [
    organization(), 
    jwt({
      jwt: {
        definePayload: (user) => ({
          id: user.user.id,
          name: user.user.name,
          orgId: user.se
        })
      }
    })
  ],
});

user is of type user: { user: User & Record<string, any>; session: Session & Record<string, any>; }; I don't see an easy way to attach data from the user's organization data to the JWT?

Originally created by @winstonpurnomo on GitHub (Feb 1, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/1328 In this code: ``` export const auth = betterAuth({ database: drizzleAdapter(db, { provider: "pg", }), plugins: [ organization(), jwt({ jwt: { definePayload: (user) => ({ id: user.user.id, name: user.user.name, orgId: user.se }) } }) ], }); ``` `user` is of type `user: { user: User & Record<string, any>; session: Session & Record<string, any>; }`; I don't see an easy way to attach data from the user's organization data to the JWT?
GiteaMirror added the locked label 2026-04-13 03:51:22 -05:00
Author
Owner

@itxtoledo commented on GitHub (Jan 12, 2026):

How did you fix this issue?

<!-- gh-comment-id:3739761485 --> @itxtoledo commented on GitHub (Jan 12, 2026): How did you fix this issue?
Author
Owner

@LewisW commented on GitHub (Feb 2, 2026):

Took me forever to figure out how, but you can access the current context with getCurrentAuthContext() and then you can add anything you like to the payload:

import {getOrgAdapter} from "better-auth/plugins";
import {getCurrentAuthContext} from "@better-auth/core/context";

// ....

      jwt({
        jwt: {
          definePayload: async ({user, session}): Promise<Record<string, any>> => {
            const { context } = await getCurrentAuthContext();
            const adapter = getOrgAdapter(context);
            const organizations = await adapter.listOrganizations(user.id);

            return {
              ...user,
              organizations: organizations.map(org => org.slug),
            }
          },
        },
      }),
<!-- gh-comment-id:3832365639 --> @LewisW commented on GitHub (Feb 2, 2026): Took me forever to figure out how, but you can access the current context with `getCurrentAuthContext()` and then you can add anything you like to the payload: ``` import {getOrgAdapter} from "better-auth/plugins"; import {getCurrentAuthContext} from "@better-auth/core/context"; // .... jwt({ jwt: { definePayload: async ({user, session}): Promise<Record<string, any>> => { const { context } = await getCurrentAuthContext(); const adapter = getOrgAdapter(context); const organizations = await adapter.listOrganizations(user.id); return { ...user, organizations: organizations.map(org => org.slug), } }, }, }), ````
Author
Owner

@GTB3NW commented on GitHub (Feb 24, 2026):

Took me forever to figure out how, but you can access the current context with getCurrentAuthContext() and then you can add anything you like to the payload:

import {getOrgAdapter} from "better-auth/plugins";
import {getCurrentAuthContext} from "@better-auth/core/context";

// ....

      jwt({
        jwt: {
          definePayload: async ({user, session}): Promise<Record<string, any>> => {
            const { context } = await getCurrentAuthContext();
            const adapter = getOrgAdapter(context);
            const organizations = await adapter.listOrganizations(user.id);

            return {
              ...user,
              organizations: organizations.map(org => org.slug),
            }
          },
        },
      }),

Perfect solution, thank you!

If anyone finds it not working, don't do what I did and put definePayload at the top level, ensure you put it into the jwt key inside the jwt() call.

<!-- gh-comment-id:3954686129 --> @GTB3NW commented on GitHub (Feb 24, 2026): > Took me forever to figure out how, but you can access the current context with `getCurrentAuthContext()` and then you can add anything you like to the payload: > > ``` > import {getOrgAdapter} from "better-auth/plugins"; > import {getCurrentAuthContext} from "@better-auth/core/context"; > > // .... > > jwt({ > jwt: { > definePayload: async ({user, session}): Promise<Record<string, any>> => { > const { context } = await getCurrentAuthContext(); > const adapter = getOrgAdapter(context); > const organizations = await adapter.listOrganizations(user.id); > > return { > ...user, > organizations: organizations.map(org => org.slug), > } > }, > }, > }), > ``` Perfect solution, thank you! If anyone finds it not working, don't do what I did and put `definePayload` at the top level, ensure you put it into the `jwt` key _inside_ the `jwt()` call.
Author
Owner

@github-actions[bot] commented on GitHub (Apr 1, 2026):

This issue has been locked as it was closed more than 7 days ago. If you're experiencing a similar problem or you have additional context, please open a new issue and reference this one.

<!-- gh-comment-id:4166557306 --> @github-actions[bot] commented on GitHub (Apr 1, 2026): This issue has been locked as it was closed more than 7 days ago. If you're experiencing a similar problem or you have additional context, please open a new issue and reference this one.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#8694