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

How do I access my access_token in a server component? #7913

Closed
jakobpucher opened this issue Jun 30, 2023 · 33 comments
Closed

How do I access my access_token in a server component? #7913

jakobpucher opened this issue Jun 30, 2023 · 33 comments
Labels
question Ask how to do something or how something works

Comments

@jakobpucher
Copy link

Question 💬

I'm logging in using NextAuth with Azure AD as the provider, which works fine.

In the NextAuth callbacks, I receive the access_token. In middleware.ts, I can use the getToken(req, secret) method and access the access_token (but what to do with it there?). In my internal API routes, the getToken(req, secret) always returns null.

I read in another question thread that this is the expected behaviour. These values are not passed to the API routes for security reasons.

NOTE: The only reasons i created the internal API routes was because there I got access to the request object which is needed to use the getToken() method

My question then becomes:

How do I access my JWT token in my server components? And if they are encrypted by next, how do I decode and use them?

My NEXTAUTH_SECRET is created with openssl rand -base64 32 (I dont know if you should say that in public )

How to reproduce ☕️

auth.ts

import { NextAuthOptions } from "next-auth";
import AzureADProvider from "next-auth/providers/azure-ad";
import { CLIENT_ID, CLIENT_SECRET, TENANT_ID } from "./utils/envPublic";

const authOptions: NextAuthOptions = {
    providers: [
        AzureADProvider({
            clientId: CLIENT_ID,
            clientSecret: CLIENT_SECRET,
            tenantId: TENANT_ID,
            authorization: {
                params: {
                    scope: "openid profile email api://myapi/my.scope",
                }
            }
        })
    ],
    secret: process.env.NEXTAUTH_SECRET,
    session: {
        strategy: "jwt"
    },
    jwt: {
        secret: process.env.NEXTAUTH_SECRET
    },
    callbacks: {
        async jwt({ token, account, user }) {
            token.accessToken = account?.access_token;
            return { ...token, ...user, ...account };
        },
        async session({ session, token, user }) {
            session.token = token.accessToken;
            session.user.token = token.accessToken;
            return session;
        },
        async redirect() {
            return "/"
        }
    },

};

export default authOptions;

My server component:

const Home = async () => {
  // How do I get the access token here?
  let response = await fetch("http://external.api.that.needs.accestoken.to.work/");
  let json = await response.json();

  return (
    <div className="flex flex-col items-center">
      <p className="p-12 hover:bg-red-600 cursor-pointer">Hello there github friends</p>
    </div>
  )
};

export default Home;

I've also done some attempts to extend the types/interfaces to store the access_token in the callbacks.
Tbh, im not really sure how this works.
next-auth-d.ts:

import NextAuth, { DefaultSession } from "next-auth";
import type { Session, Account } from "next-auth";

declare module "next-auth" {

  interface Session {
    token?: accessToken;
    user: {
      token?: accessToken;
    } & DefaultSession["user"];
  }
  interface Account {
    access_token: accessToken;
    user: {
      token?: accessToken;
    } & DefaultSession["user"];
  }
}

Contributing 🙌🏽

Yes, I am willing to help answer this question in a PR

@jakobpucher jakobpucher added the question Ask how to do something or how something works label Jun 30, 2023
@jakobpucher
Copy link
Author

I tried to get the token from cookies() in my server components and log them.
2 tokens get logged:
next-auth.session-token.0
next-auth.session-token.1

I must've been doing something wrong in the callbacks to store 2 of them. However, both signatures are invalid according to jwt.io when i copy them there.

import { cookies } from "next/dist/client/components/headers";

const Home = async () => {

  const cooks = cookies();
  const allCookies = cooks.getAll();
  allCookies.forEach((cookie) => {
    console.log(cookie.name);
    console.log(cookie.value);
  });

  return (
    <div className="flex flex-col items-center">
      <p className="p-12 hover:bg-red-600 cursor-pointer">Hello there github friends</p>
    </div>
  )
};

export default Home;

@balazsorban44
Copy link
Member

check out the docs https://next-auth.js.org/configuration/nextjs#in-app-directory

@Kevin-McGonigle
Copy link

The docs don't really cover this question (as far as I can see). They show how to get the session, sure, but not how to get the access token in a server component. getToken works fine for route handlers, but not for server components since there's no req to pass in. I think this should be easy enough to implement though, taking an approach similar to getServerSession - I'll give it a go!

@stayclaxxy
Copy link

Sorry to open this thread back up - I am in the same exact scenario currently and have not found a viable solution. I would prefer to not have to access the cookies to extract the JWT within the server component. Has anyone been able to find a way to get this done? On my client component it returns all of the properties i've defined in the session callback, but in the server component, getServerSession only returns the user object with name, email, image properties and nothing else. I am using the AzureB2C provider.

@joonasjarvinen92
Copy link

joonasjarvinen92 commented Dec 15, 2023

I managed to get the access_token by creating a callback in the authOption object:

// app/api/auth/[...nextauth]/route.ts


const authOptions: NextAuthOptions = {
    providers: [
        AzureADProvider({
            clientId: process.env.AZURE_AD_CLIENT_ID ?? '',
            clientSecret: process.env.AZURE_AD_CLIENT_SECRET ?? '',
            tenantId: process.env.AZURE_AD_TENANT_ID,
        }),
    ],
    session: {
        strategy: 'jwt',  // <-- make sure to use jwt here
        maxAge: 30 * 24 * 60 * 60,
    },
    callbacks: {
        jwt: async ({ token, user, account }) => {
            if (account && account.access_token) {
                token.accessToken = account.access_token // <-- adding the access_token here
            }
            return token
        },
    },
    secret: process.env.NEXTAUTH_SECRET,
}

const handler = NextAuth(authOptions)

export { handler as GET, handler as POST }

Now you should be able to see the accessToken when calling getToken()

// app/api/test/route.ts


import { NextRequest, NextResponse } from 'next/server'
import { getToken } from 'next-auth/jwt'

export async function GET(req: NextRequest) {
    const token = await getToken({
        req,
        secret: process.env.NEXTAUTH_SECRET ?? '',
    })

    console.log('token.accessToken: ', token?.accessToken)

    return NextResponse.json({})
}

@Yazan-Ali-01
Copy link

const token = await getToken({
req,
secret: process.env.NEXTAUTH_SECRET ?? '',
})

did you manage anyway to solve this
especially that we cant modify the server session and that it is always having only name, email, image only

@raulclaudino
Copy link

raulclaudino commented Dec 23, 2023

import { getToken } from 'next-auth/jwt';
export async function PATCH(req: NextRequest, route: { params: RouteParams }) {
    const token: any = await getToken({ req, raw: true }); /* eyJhbGciOiJkaXIiLCJlbmMiOiJBM... */
}

@raulclaudino
Copy link

const token = await getToken({
req,
secret: process.env.NEXTAUTH_SECRET ?? '',
})

did you manage anyway to solve this especially that we cant modify the server session and that it is always having only name, email, image only

const token = await getToken({
req,
secret: process.env.NEXTAUTH_SECRET ?? '',
})

did you manage anyway to solve this especially that we cant modify the server session and that it is always having only name, email, image only

@Yazan-Ali-01 https://next-auth.js.org/getting-started/client#updating-the-session

@Yazan-Ali-01
Copy link

const token = await getToken({
req,
secret: process.env.NEXTAUTH_SECRET ?? '',
})

did you manage anyway to solve this especially that we cant modify the server session and that it is always having only name, email, image only

const token = await getToken({
req,
secret: process.env.NEXTAUTH_SECRET ?? '',
})

did you manage anyway to solve this especially that we cant modify the server session and that it is always having only name, email, image only

@Yazan-Ali-01 https://next-auth.js.org/getting-started/client#updating-the-session

this would update the server session or the client session ??
also where are you using this code
import { getToken } from 'next-auth/jwt'; export async function PATCH(req: NextRequest, route: { params: RouteParams }) { const token: any = await getToken({ req, raw: true }); /* eyJhbGciOiJkaXIiLCJlbmMiOiJBM... */ }
is it inside middleware.js ??
and can you share your [...nextauth]/route.js file please ??
maybe the callbacks are the problem for me
thanks

@joonasjarvinen92
Copy link

joonasjarvinen92 commented Jan 2, 2024

I have made some changes, so my /app/api/auth/[...nextauth]/route.ts looks like this:

import NextAuth from 'next-auth/next'
import { authOptions } from '@/auth'

const handler = NextAuth(authOptions)

export { handler as GET, handler as POST }

the authOptions coming from /auth.ts is shown below. Do note that I added the session callback along with the jwt callback,
so the jwt can be accessed from React components

// /auth.ts

import {
    GetServerSidePropsContext,
    NextApiRequest,
    NextApiResponse,
} from 'next'
import { NextAuthOptions, getServerSession } from 'next-auth'
import AzureADProvider from 'next-auth/providers/azure-ad'

const authOptions: NextAuthOptions = {
    providers: [
        AzureADProvider({
            clientId: process.env.AZURE_AD_CLIENT_ID ?? '',
            clientSecret: process.env.AZURE_AD_CLIENT_SECRET ?? '',
            tenantId: process.env.AZURE_AD_TENANT_ID,
        }),
    ],
    session: {
        strategy: 'jwt',
        maxAge: 30 * 24 * 60 * 60, // 30 days
    },
    callbacks: {
        jwt: async ({ token, user, account }) => {
            if (account && account.access_token) {
                // set access_token to the token payload
                token.accessToken = account.access_token
            }

            return token
        },
        redirect: async ({ url, baseUrl }) => {
            return baseUrl
        },
        session: async ({ session, token, user }) => {
            // If we want to make the accessToken available in components, then we have to explicitly forward it here.
            return { ...session, token: token.accessToken }
        },
    },
    pages: {
        signIn: '/',
    },
    secret: process.env.NEXTAUTH_SECRET,
}

function auth(  // <-- use this function to access the jwt from React components
    ...args:
        | [GetServerSidePropsContext['req'], GetServerSidePropsContext['res']]
        | [NextApiRequest, NextApiResponse]
        | []
) {
    return getServerSession(...args, authOptions)
}

export { authOptions, auth }

You can now import the auth function from above, and use it inside components

// /app/[locale]/(auth)/dashboard/overview/page.tsx

import { auth } from '@/auth'

export default async function Page() {
    const session = await auth()
    console.log('jwt: ', session?.token)
    return <></>
}

@linus-jansson
Copy link

callbacks: {
    jwt: async ({ token, user, account }) => {
        if (account && account.access_token) {
            // set access_token to the token payload
            token.accessToken = account.access_token
        }

        return token
    },
    redirect: async ({ url, baseUrl }) => {
        return baseUrl
    },
    session: async ({ session, token, user }) => {
        // If we want to make the accessToken available in components, then we have to explicitly forward it here.
        return { ...session, token: token.accessToken }
    },
},

This works! But have you made use of refresh token rotation? My IdentityProvider puts an short expire time on the token so its useless after 5min, and next auth doesn't automatically refresh the access token when the it expires.

Feels like its something that should be handle automatically as long as the session is still valid.

@SRTigers98
Copy link

@linus-jansson I had the same problem with the refresh token rotation and solved it by adapting the jwt callback. I used the code from the refresh token rotation guide. Additionally, since the callback is only called when the session is created or updated (described in the jwt callback documentation), I created a middleware that calls the getServerSession function to make sure the access token is always up to date when an api function is called.

I hope this helps with your problem.

@abdushkur
Copy link

abdushkur commented Feb 9, 2024

import { cookies } from 'next/headers'
 
export default function Page() {
  const cookieStore = cookies()
  const theme = cookieStore.get('theme')
  return '...'
}

@avillegastorres
Copy link

@linus-jansson I had the same problem with the refresh token rotation and solved it by adapting the jwt callback. I used the code from the refresh token rotation guide. Additionally, since the callback is only called when the session is created or updated (described in the jwt callback documentation), I created a middleware that calls the getServerSession function to make sure the access token is always up to date when an api function is called.

I hope this helps with your problem.

Do you have a snippet with the example? Thanks!

@SRTigers98
Copy link

@avillegastorres I used the following code for the jwt callback to refresh the token issued by a keycloak server:

// ...
jwt: async ({ token, account }) => {
  if (account) {
    return {
      accessToken: account.access_token || "",
      expiresAt: account.expires_at || 0,
      refreshToken: account.refresh_token || "",
    };
  }

  if (Date.now() < token.expiresAt * 1000) {
    return token;
  }

  return await refreshToken(token);
},
// ...

async function refreshToken(token: JWT): Promise<JWT> {
  try {
    const tokenEndpoint = `${
      oauthHost + oauthIssuer
    }/protocol/openid-connect/token`;

    // https://nuxt.com/docs/getting-started/data-fetching#fetch
    const response = await $fetch<TokenSet>(tokenEndpoint, {
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
      },
      body: new URLSearchParams({
        client_id: oauthClient,
        client_secret: oauthSecret,
        grant_type: "refresh_token",
        refresh_token: token.refreshToken,
      }),
      method: "POST",
    });

    return {
      ...token,
      accessToken: response.access_token || "",
      expiresAt: response.expires_at || 0,
      refreshToken: response.refresh_token ?? token.refreshToken,
    };
  } catch (error) {
    console.error("Error refreshing access token", error);
    return { ...token, error: "RefreshAccessTokenError" as const };
  }
}

declare module "next-auth/jwt" {
  interface JWT {
    accessToken: string;
    expiresAt: number;
    refreshToken: string;
    error?: "RefreshAccessTokenError";
  }
}

I also implemented a middleware to call the getServerSession function:

// https://nuxt.com/docs/guide/directory-structure/server#server-middleware
export default defineEventHandler(async (event) => {
  // Trigger JWT callback to refresh token if needed
  await getServerSession(event);
});

For my project I used Nuxt 3 with the Sidebase Auth integration which uses next-auth@4.22.5, so some things may need to be adjusted.

@Nidroide
Copy link

...
        session: async ({ session, token, user }) => {
            // If we want to make the accessToken available in components, then we have to explicitly forward it here.
            return { ...session, token: token.accessToken }
...

Be aware that including the access token in the session will also expose it to the client (getSession, useSession...).

@avillegastorres
Copy link

avillegastorres commented Feb 13, 2024

Hey guys, I did a proxy API route on my next.js API folder that brings me the access token. My code looks like this.

//This file lives in src/app/api/proxy/route.ts
import { getToken } from "next-auth/jwt";
import { NextRequest, NextResponse } from "next/server";

export async function PATCH(req: NextRequest) {
  const token = await getToken({
    req,
  });

  if (!token) {
    return NextResponse.json(
      {
        message: "Unauthorized",
      },
      {
        status: 401,
      }
    );
  }

//The "access_toke" name is up to you; you need to check how you pass it on the JWT callback
  return Response.json({ accessToken: token["access_token"] });
}

Now, on my server component, I'm calling it like this:

// src/app/page.tsx
import { getServerSession } from "next-auth";
import { headers } from "next/headers";
import { redirect } from "next/navigation";
import Landing from "./components/Landing";
import { Locale } from "./lib/i18n/dictionaries/types";

async function IndexPage({ params: { lang } }: { params: { lang: Locale } }) {
  const session = await getServerSession();

  const token = await fetch("http://localhost:3000/api/proxy", {
    method: "PATCH",
    headers: headers(), // this is important without, the API will not be able to extract the token from the header
  });

  console.log(await token.json());

  if (!session || !session.user) {
    redirect("/login");
  }

  return <Landing lang={lang} />;
}

export default IndexPage;

why I choose this

Ok, I decided to do it like this because I want to keep the access token information private from the client; the @joonasjarvinen92 works great if you don't mind that, but in my case, it wasn't an option. I hope the Next Auth introduces a better way to do this; in the meantime, I'll use this.

Another note is that you still need the JWT callback for this to work since it is the only way to add the access token into the JWT that NextAuth creates as part of the JWT strategy.

References:

@benedwards44
Copy link

Hey guys, I did a proxy API route on my next.js API folder that brings me the access token. My code looks like this.

//This file lives in src/app/api/proxy/route.ts
import { getToken } from "next-auth/jwt";
import { NextRequest, NextResponse } from "next/server";

export async function PATCH(req: NextRequest) {
  const token = await getToken({
    req,
  });

  if (!token) {
    return NextResponse.json(
      {
        message: "Unauthorized",
      },
      {
        status: 401,
      }
    );
  }

//The "access_toke" name is up to you; you need to check how you pass it on the JWT callback
  return Response.json({ accessToken: token["access_token"] });
}

Now, on my server component, I'm calling it like this:

// src/app/page.tsx
import { getServerSession } from "next-auth";
import { headers } from "next/headers";
import { redirect } from "next/navigation";
import Landing from "./components/Landing";
import { Locale } from "./lib/i18n/dictionaries/types";

async function IndexPage({ params: { lang } }: { params: { lang: Locale } }) {
  const session = await getServerSession();

  const token = await fetch("http://localhost:3000/api/proxy", {
    method: "PATCH",
    headers: headers(), // this is important without, the API will not be able to extract the token from the header
  });

  console.log(await token.json());

  if (!session || !session.user) {
    redirect("/login");
  }

  return <Landing lang={lang} />;
}

export default IndexPage;

why I choose this

Ok, I decided to do it like this because I want to keep the access token information private from the client; the @joonasjarvinen92 works great if you don't mind that, but in my case, it wasn't an option. I hope the Next Auth introduces a better way to do this; in the meantime, I'll use this.

Another note is that you still need the JWT callback for this to work since it is the only way to add the access token into the JWT that NextAuth creates as part of the JWT strategy.

References:

@avillegastorres I really like this approach. As mentioned, it keeps the token on the server and means I have a central location to retrieve the token from my various server components.

The issue I have however is although this works locally, I retrieve an error when running in Production (which is on Vercel):
Headers cannot be modified. Read more: https://nextjs.org/docs/app/api-reference/functions/headers

It seems that passing the NextJS headers() to the PATCH route handler seems to throw this error 🙄 I can't see anything that is actually modifying the headers, but unfortunately don't have any other ideas on this other than storing the token on the client side which I was hoping to avoid.

@oskarssylwan
Copy link

I tried to get the token from cookies() in my server components and log them. 2 tokens get logged: next-auth.session-token.0 next-auth.session-token.1

I must've been doing something wrong in the callbacks to store 2 of them. However, both signatures are invalid according to jwt.io when i copy them there.

I also got 2 session tokens and was confused by it. It looks like NextAuth is chunking the session cookie it it is too large. You can see it if you turn on debug mode

@oskarssylwan
Copy link

So to summarise we have 2 options?

  1. Expose the access_token in the session which is unfavourable since it will expose it to the client
  2. Make calls to a route handler inside the components to get it, which is seen as an anti pattern by Vercel because of the extra network calls.

Is there really no better way to get it?

@starlight-akouri
Copy link

It seems like the new universal auth() method in v5 is supposed to handle this, but it does not look like it's implemented yet? Can someone confirm?

@impact-ls
Copy link

impact-ls commented Mar 19, 2024

In the new docs it says that all should be replaced with auth(), but as of now it only returns a session.

Maybe a stupid question, but why is exposing accessToken to the client bad? Isn't it usually stored in the cookies and is encrypted anyway?

It seems adding a Route Handler just for getting the accessToken via getToken is not necessary if we can use getToken on the server. This way we get rid of unnecessary network calls.

I am still waiting for the new docs to give an example or explain how to do it properly in v5. I have two problems:

  1. I have trouble refreshing the token. I followed the docs but I don't know how to update the token with the new one. getToken from next-auth/jwt does not update after jwt callback returns the new token.

  2. I would like to automatically signOut when the refresh token expires. Is it possible from the server (inside the callback)? It worked for me except that there is an error thrown that the cookies are modified not in the Server Action or a Route Handler, so I assume it was not intended to be done this way.

@teapot2
Copy link

teapot2 commented Apr 11, 2024

next-auth is awful lol

@alarv
Copy link

alarv commented Jun 4, 2024

It's 2024 and the most popular JS framework and the most popular auth library to go with it does not return the access token, I thought this is trivial.

@Yazan-Ali-01
Copy link

I believe the problem got fixed in the newer next auth version with the gloabl auth()

@joostfarla
Copy link

I faced the same issue, and started a thread on Discord: https://discord.com/channels/1200116961590399008/1257260179683283048

It might help if others provide additional input there.

@gaganbiswas
Copy link

gaganbiswas commented Jul 14, 2024

On nextjs 14, I got the access_token in the rsc, actions and routes by creating a cookie in the jwt() function using cookies() from next/headers. Doing this ensured that my access_token can't be accessed from the client or by going to /api/auth/session. I also handled some situations like deleting my cookies on expiry syncing its expiry with my session cookies from next-auth.

async jwt({ token, user }): Promise<JWT | null> {
      const cookie = cookies();
      if (user) {
        const accessDecode = jwtDecode(user.accessToken);

        const userProfile: User = {
          id: token.sub,
          name: user.name,
          email: user.email,
          image: user.image,
          accessToken: "",
          refreshToken: "",
          username: user.username,
        };

        cookie.set("access-token", user.accessToken, {
          expires: accessDecode.exp! * 1000,
          httpOnly: true,
          secure: process.env.NODE_ENV === "production",
          sameSite: "lax",
        });

        return {
          access_token: user.accessToken,
          expires_at: accessDecode.exp as number,
          refresh_token: user.refreshToken,
          user: userProfile,
        };
      } else if (Date.now() < token.expires_at * 1000) {
        return token;
      } else {
        if (!token.refresh_token) {
          cookie.delete("access-token");
          throw new Error("Missing refresh token");
        }

        try {
          const { data } = await axios.get(
            process.env.API_URL + "/user/generate-new-refresh-token",
            {
              headers: {
                Authorization: token.access_token as string,
                refreshToken: token.refresh_token as string,
              },
            }
          );

          if (data.error) throw new Error("Bad request");

          const accessDecode = jwtDecode(data.data.accessToken);

          cookie.set("access-token", data.data.accessToken, {
            expires: accessDecode.exp! * 1000,
            httpOnly: true,
            secure: process.env.NODE_ENV === "production",
            sameSite: "lax",
          });

          return {
            // Keep the previous token properties
            ...token,
            access_token: data.data.accessToken,
            expires_at: accessDecode.exp as number,
            refresh_token: data.data.refreshToken,
          };
        } catch (error) {
          cookie.delete("access-token");
          return null;
        }
      }
    },
    async session({ session, token }) {
      if (token.user) {
        // @ts-ignore
        session.user = token.user as User;
      }

      return session;
    },
  },
  session: {
    maxAge: 60 * 60,
  },

I guess this is quite a messy approach but atleast for now it insures that my access_token is safe in the cookies and is not exposed to the client. Hope, next-auth fixes this soon. :D

@anaclumos
Copy link

You can use this in Next.js App Router!

import { Suspense } from "react"
import { getServerSession } from "next-auth/next"
import { Session } from "@/types/session"
import { authOptions } from "@/lib/auth"
import { cookies } from 'next/headers';

export default async function JobsPage() {
  const session: Session | null = await getServerSession(authOptions)

  if (!session) {
    redirect("/profile") // should not happen due to the middleware
  }

+  const cookieStore = cookies();
+  const sessionToken = cookieStore.get('next-auth.session-token');

...

@aayushgelal
Copy link

I made it working by passing nextAuthOptions as parameter in getServerSession function. This should work for you as well.
const session = await getServerSession(nextAuthOptions); // 👈 added this
where nextAuthOptions = ({
providers: ....

});

@alinasiri8102
Copy link

alinasiri8102 commented Jul 27, 2024

i'm using this approach in one of my server Actions and it works fine:
#5792 (comment)

import { headers, cookies } from "next/headers";
import { getToken } from "next-auth/jwt";

 const token = await getToken({
    req: {
      headers: Object.fromEntries(headers()),
      cookies: Object.fromEntries(
        cookies()
          .getAll()
          .map((c) => [c.name, c.value])
      ),
    },
  });

  console.log(token);

@arohman84
Copy link

arohman84 commented Aug 4, 2024

cookie.delete("access-token");
          return null;

unfortunately I got error for next 14.2.5 and next-auth 5.0.0-beta.20 when using cookie from next/headers, here's the server log:

Error: Cookies can only be modified in a Server Action or Route Handler.

so weird the console.log visible on server log but auth said this is not server action .... hmmmmm

@gaganbiswas
Copy link

Error: Cookies can only be modified in a Server Action or Route Handler.

Well you can create a deleteCookie action in action.ts and then call the deleteCookie fn from the catch block.

I actually dropped the idea of using next-auth cz i was getting into lot of problems with the beta version and i went ahead and used my own auth management using providers and interceptors.

@dion-blutui
Copy link

@avillegastorres Any idea why I get this error on calling getToken() inside a API route.

  const token = await getToken({
    req,
    secret
  })

Error
Argument of type '{ req: NextRequest; secret: string; }' is not assignable to parameter of type 'GetTokenParams<false>'. Property 'salt' is missing in type '{ req: NextRequest; secret: string; }' but required in type 'GetTokenParams<false>'.

auth.ts

  jwt({ token, profile }) {
    if (profile) {
      token.id = profile.id
      token.image = profile.avatar_url || profile.picture
      token.accessToken = profile.accessToken
    }
    return token
  },
  session: ({ session, token }) => {
    if (session?.user && token?.id) {
      session.user.id = String(token.id)
    }

    return session
  },
  authorized({ auth }) {
    return !!auth?.user // this ensures there is a logged in user for -every- request
  }
},```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Ask how to do something or how something works
Projects
None yet
Development

Successfully merging a pull request may close this issue.