Closed nfts2me closed 1 year ago
have exactly the same issue.
Seems like getCsrfToken
in the authorize
method is throwing error
We cannot recreate the issue with the provided information. Please add a reproduction in order for us to be able to investigate.
incomplete
label?To be able to investigate, we need access to a reproduction to identify what triggered the issue. We prefer a link to a public GitHub repository (template), but you can also use a tool like CodeSandbox or StackBlitz.
To make sure the issue is resolved as quickly as possible, please make sure that the reproduction is as minimal as possible. This means that you should remove unnecessary code, files, and dependencies that do not contribute to the issue.
Please test your reproduction against the latest version of NextAuth.js (next-auth@latest
) to make sure your issue has not already been fixed.
Ensure the link is pointing to a codebase that is accessible (e.g. not a private repository). "example.com", "n/a", "will add later", etc. are not acceptable links -- we need to see a public codebase. See the above section for accepted links.
Issues with the incomplete
label that receives no meaningful activity (e.g. new comments with a reproduction link) are closed after 7 days.
If your issue has not been resolved in that time and it has been closed/locked, please open a new issue with the required reproduction. (It's less likely that we check back on already closed issues.)
Anyone experiencing the same issue is welcome to provide a minimal reproduction following the above steps. Furthermore, you can upvote the issue using the :+1: reaction on the topmost comment (please do not comment "I have the same issue" without repro steps). Then, we can sort issues by votes to prioritize.
We look into every NextAuth.js issue and constantly monitor open issues for new comments.
However, sometimes we might miss one or two. We apologize, and kindly ask you to refrain from tagging core maintainers, as that will usually not result in increased priority.
Upvoting issues to show your interest will help us prioritize and address them as quickly as possible. That said, every issue is important to us, and if an issue gets closed by accident, we encourage you to open a new one linking to the old issue and we will look into it.
Getting the same issue after installing v4.21.1
reverted back to 4.20.1
to ensure things are working.
1 - Scaffold new project - pnpm create t3-app@latest;
2 - Modify ./src/server/auth.ts
under the getServerAuthSession
as follows:
File: ./src/server/auth.ts
// ...
// NOTE: This is needed for passing the `req` to the authOptions to verify the csrf with the nonce for Sign-In With Ethereum
/**
* Wrapper for `getServerSession` so that you don't need to import the `authOptions` in every file.
*
* @see https://next-auth.js.org/configuration/nextjs
*/
export const getServerAuthSession = async (ctx: {
req: GetServerSidePropsContext["req"];
res: GetServerSidePropsContext["res"];
}) => {
// Add next two lines to retrieve csrf token
const token = await getCsrfToken({ req: ctx.req });
console.log({ token });
return getServerSession(ctx.req, ctx.res, authOptions);
};
3 - Run the dev environment and see error in terminal - pnpm dev
With version next-auth@4.20.1
pnpm dev;
# Output:
# {
# token: '2f9e2ad7596966b47e4d631ad3cbe48d246781b91f8680a840906a02529aacb3'
# }
With version next-auth@4.21.1
pnpm dev;
# Output:
# [next-auth][error][CLIENT_FETCH_ERROR]
# https://next-auth.js.org/errors#client_fetch_error invalid json response body at http://localhost:3000/api/auth/csrf reason: # Unexpected token E in JSON at position 0 {
# error: {
# message: 'invalid json response body at http://localhost:3000/api/auth/csrf reason: Unexpected token E in JSON at # position 0',
# stack: 'FetchError: invalid json response body at http://localhost:3000/api/auth/csrf reason: Unexpected token E in JSON # at position 0\n' +
# ' at /Users/username/path/to/test-t3-app/node_modules/.pnpm/next@13.2.4_react-# dom@18.2.0_react@18.2.0/node_modules/next/dist/compiled/node-fetch/index.js:1:51220\n' +
# ' at runMicrotasks (<anonymous>)\n' +
# ' at processTicksAndRejections (node:internal/process/task_queues:96:5)',
# name: 'FetchError'
# },
# url: 'http://localhost:3000/api/auth/csrf',
# message: 'invalid json response body at http://localhost:3000/api/auth/csrf reason: Unexpected token E in JSON at # position 0'
# }
# { token: undefined }
@balazsorban44 does the above complete the section required for the steps to reproduce to remove the incomplete tag?
I get the same Error when I invoke await getCsrfToken({ req })
inside the authorize method of a credentials provider.
I think I found the issue or at least some more details why this happens.
The original error when decoding the response, in fetchData which is invoked by getCsrfToken, to text instead of json, it says: Error: This action with HTTP POST is not supported by NextAuth.js
In fetchData there is a check if the request has a body
if (req?.body) {
options.body = JSON.stringify(req.body)
options.method = "POST"
}
if so, fetching the Csrf-Token is done with a POST request which doesnt seem to work.
You can check when running a POST request to http://localhost:3000/api/auth/csrf it responses with Error: This action with HTTP POST is not supported by NextAuth.js
Maybe the fetchData method has changed and introduced this bug?
@codingwithmanny I would like a repro that I can easily clone and can start the server to reproduce the issue. I'm not familiar with the internals/code of t3-app
in detail, so it would be nice if you could create a reproduction without it, just the bare minimal issue. Thanks. Not sure how/when getServerAuthSession
is being used.
@prometixX It's unclear what you are trying to achieve. What you are describing seems to be unnecessary. When the authorize
callback is invoked, the request has already been verified against CSRF. If you are calling an external endpoint, our CSRF protection should not be used for it. If you are invoking another endpoint in your app, just import the logic rather than doing a subsequent fetch
call.
Absolutely @balazsorban44 Here is a repository: https://github.com/codingwithmanny/t3-app-siwe
The only thing that needs to be done is update the version pnpm add next-auth@latest
.
The README should show how to set it up.
For some additional context, this is an implementation with Sign-In With Ethereum (SIWE) and Create-t3-stack, and it'll require a Crypto wallet like https://metamask.io.
The way that we're leverage getCsrfToken
is to leverage and use as a nonce needed for the SIWE wallet message prompt.
@balazsorban44 I basically had the same usecase that @codingwithmanny is describing.
Using the getCsrfToken
in the authorize method of a credentials provider to verify the SIWE message.
Using getCsrfToken
is how they are doing it in the Docs here https://docs.login.xyz/integrations/nextauth.js.
async authorize(credentials) {
try {
const siwe = new SiweMessage(JSON.parse(credentials?.message || "{}"))
const nextAuthUrl = new URL(process.env.NEXTAUTH_URL)
const result = await siwe.verify({
signature: credentials?.signature || "",
domain: nextAuthUrl.host,
nonce: await getCsrfToken({ req }),
})
if (result.success) {
return {
id: siwe.address,
}
}
return null
} catch (e) {
return null
}
},
But due to some change within NextAuth (maybe inside fetchData) this doesnt seem to work anymore.
I understand that it might be an unnecessary overhead to call a fetch inside the api route (authorize method), since we have access to the cookie and NextAuth environment variables anyways but I didnt want to go the whole way of reimplementing the validation logic, so I thought using getCsrfToken
(and with that a extra fetch) is ok for my usecase.
I think a lot of people will have this error since basically every SIWE + NextAuth tutorial uses the getCsrfToken
method.
@prometixX I was thinking about this as well, where you could have a separate endpoint for the nonce and still verify the source request via csrf. I wonder if that's the new direction we should be taking with SIWE.
So after thinking about it/having a look, this code block is the issue:
getCSRFToken
is not very ideal on the backend, since it will invoke another endpoint and if you are using something like Vercel/Serverless, it might be the cause of slower response times.
Longer term, I would recommend finding an alternative solution, or as a workaround, instead of passing the whole req
(which is a POST request with a body when in the authorize()
call's context), you can just pass an object with the cookies, since that's the only things we need:
So this should solve the issue:
- const nonce = await getCsrfToken({ req });
+ const nonce = await getCsrfToken({ req: { headers: req.headers } });
This will make sure that the following code block is not triggered, making the response invalid: https://github.com/nextauthjs/next-auth/blob/7a8c0068c4c42761b54eff496f6cb8820b54b5d1/packages/next-auth/src/client/_utils.ts#L47-L50
I would consider this kind of an edge case/not something we have official built-in support for, so I'm inclined to close the issue as it's not a bug, but I hope my above suggestion will be sufficient.
- const nonce = await getCsrfToken({ req }); + const nonce = await getCsrfToken({ req: { headers: req.headers } });
I was re-checking the docs, and I still think that NextAuth introduced a bug, or the docs are wrong: Check this: https://next-auth.js.org/getting-started/client#server-side-example It explicitly gives the example for the server side to be done as the 'wrong?' code.
I would be nice to change either.
Resolved w/ downgrade to next-auth@4.20.1
The issue still persists w/ on next-auth
with app dir
const nonce = await getCsrfToken({ req: { headers: req.headers } });
Resolved w/ downgrade as the comment above
Getting the same issue after installing
v4.21.1
reverted back to4.20.1
to ensure things are working.
thanks
Suddenly starting having the same issue with getSession. Without updating, I was on 4.19.0
Updating to 4.20.1 fixes it Updating to 4.21.1 or latest (4.24.4) makes the error appear again
Similar to what happens with getCsrfToken
, this also workarounds the issue:
const session = await getSession({ req: { headers: req.headers } });
but generates TS errors
Good morning
I was managed to resolve an issue by using
const session = await getServerAuthSession(context);
instead of
const session = await getSession(context);
Good morning I was managed to resolve an issue by using
const session = await getServerAuthSession(context);
instead ofconst session = await getSession(context);
im using server session but still getting the issue.
I was facing the same issue in production when I was trying to deploy to Vercel. What worked for me was turning off the Vercel Authentication in Project Settings > Deployment Protection. Hope this helps!
Environment
System: OS: macOS 13.3 CPU: (8) arm64 Apple M2 Memory: 1.25 GB / 16.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 16.17.0 - ~/.nvm/versions/node/v16.17.0/bin/node Yarn: 1.22.19 - ~/.nvm/versions/node/v16.17.0/bin/yarn npm: 9.6.3 - ~/development/nfts2me/nfts2me/node_modules/.bin/npm Browsers: Brave Browser: 105.1.43.93 Chrome: 112.0.5615.49 Firefox: 110.0.1 Safari: 16.4
Reproduction URL
not-available
Describe the issue
After upgrading from next-auth@4.20.1 to next-auth@4.21.1 we're facing this error: