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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

calling getToken from GetServerSideProps #4609

Closed
Crane101 opened this issue May 23, 2022 · 5 comments 路 Fixed by #4659
Closed

calling getToken from GetServerSideProps #4609

Crane101 opened this issue May 23, 2022 · 5 comments 路 Fixed by #4659
Assignees
Labels
good first issue Good issue to take for first time contributors TypeScript Issues relating to TypeScript

Comments

@Crane101
Copy link

Crane101 commented May 23, 2022

Question 馃挰

Context

  • I have configured NextAuth to add the account.access_token to my jwt token on login/signup.
  • I want to pass the token to my data API (separate environment) in GetServerSideProps to get my hands on the data I need to render the page.
  • I've spent a large amount of time trawling the forums, trying to find the answer myself before posting on here.

Problem?

So my problem is that getToken() expects a req param of NextRequest | NextApiRequest, but inside GetServerSideProps the context.req prop has a type of IncomingMessage & { cookies: NextApiRequestCookies }, so understandably it throws the toys when I try and make the call to getToken using it.

Existing Workarounds

To get around this issue, my current bag of options are:

  • Call getToken with context.req as any - this works fine, but casting to any tears at my soul.
  • Add account.access_token to the session (in addition to the token) so I can get hold of it via getSession(). This works, but I dislike conceding to add the access token in to more places than it absolutely needs to be.
  • Call the decode method from next-auth/jwt manually and extract the token.

Question

How should I get hold of the decoded JWT token in GetServerSideProps when using Typescript?
I don't believe for a second that I have exposed any sort of flaw in the NextAuth code, and I doubt I'm the first person to want to do this, so there's gotta be something obvious I'm missing here.

How to reproduce 鈽曪笍

import { GetServerSideProps } from 'next';
import { getToken } from 'next-auth/jwt';

const SomeComponent = (props: { someData: SomeData }) => (
  <div>{props.someData}</div>
);

export const getServerSideProps: GetServerSideProps = async context => {
  const token = await getToken({
    req: context.req,
    secret: SECRET_VALUE,
  });

  const someData = await getSomeData(token?.accessCode);

  return {
    props: {
      someData,
    },
  };
};

export default SomeComponent;

Contributing 馃檶馃徑

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

@Crane101 Crane101 added question Ask how to do something or how something works TypeScript Issues relating to TypeScript labels May 23, 2022
@schorfES
Copy link

Hello @Crane101, you're not the only one. I ran into this issue today as well. In pure JS, it seem to work as described in #720 (works for me when ignoring the type checks for testing). So it seems to be a typing issue...

@Crane101
Copy link
Author

Meh, I guess I'll just bury my context.req as any deep inside a helper function and try to forget about it... I just hope I'll be able to sleep knowing it's there.

Happy to explore implementing a fix if I get a nod from one of the RepoLords though.

@schorfES
Copy link

schorfES commented May 27, 2022

Yes, I am doing something similar right now. Since I extend the token with additional data I am using a custom getToken util that types the extended token. I am using this util to patch the typing. It looks somehow like this right now:

import { IncomingMessage } from 'http';

import { NextApiRequest } from 'next';
import { JWT, getToken as getAuthToken } from 'next-auth/jwt';
import { NextApiRequestCookies } from 'next/dist/server/api-utils'; // ugly import path!
import { NextRequest } from 'next/server';

interface ExtendedJWT extends JWT {
  foo: string | null;
}

type GetServerSidePropsRequest = IncomingMessage & { cookies: NextApiRequestCookies };

export type Request = NextRequest | NextApiRequest | GetServerSidePropsRequest;

export const getToken = async (request: Request): Promise<ExtendedJWT | undefined> => {
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
  const token = await getAuthToken({ req: request as any });
  if (!token) {
    return;
  }

  if ('foo' in token) {
    return {
      ...token,
      foo: (typeof token.foo === 'string') ? token.foo : null,
    };
  }
};

I would love to see a PR that fixes this typing and allows me to remove the as any from my code.

@mikebuilds
Copy link

+1 on this issue. Looks like misconfigured types.

Packages:
next: 12.1.6
next-auth: 4.1.4

@balazsorban44
Copy link
Member

balazsorban44 commented May 31, 2022

Please, there is no need to be dramatic, let's use welcoming language as reflected in our Code of Conduct: https://github.com/nextauthjs/next-auth/blob/main/CODE_OF_CONDUCT.md#our-standards

The source code is publicly available and you marked "Yes, I am willing to help answer this question in a PR".

This seems to be an easy fix, check out the source code here:

/** The request containing the JWT either in the cookies or in the `Authorization` header. */
req: NextRequest | NextApiRequest

Feel free to open a PR. 馃憤 馃挌

UPDATE: Done in #4659

@balazsorban44 balazsorban44 added good first issue Good issue to take for first time contributors and removed question Ask how to do something or how something works labels May 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good issue to take for first time contributors TypeScript Issues relating to TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants