Next-auth: CSRF and POST with multipart/form-data

Created on 7 Feb 2019  路  4Comments  路  Source: nextauthjs/next-auth

How can I pass _csrf value with 'Content-Type': 'multipart/form-data' ?

I want to upload files on the server but files could be sent only in 'multipart/form-data' form. In this case, csurf check not working and server return 404 with "Error: CSRF token missing" message

help wanted question

Most helpful comment

After some digging I found a solution for this. You need to override the csrf settings to blacklist your routes that use multipart/form-data. You could manually add lusca back in to those routes, the issue is the order in which the express middleware is being used.

nextApp
.prepare()
.then(() => {
  return nextAuthConfig();
})
.then(nextAuthOptions => {
  // Override lusca settings so we can allow multipart form submissions
  nextAuthOptions.csrf = { blacklist: ['/api/upload'] };
  return nextAuth(nextApp, nextAuthOptions);
})

Here's the full lusca configuration options:
https://github.com/krakenjs/lusca#luscacsrfoptions

And more info on the express middleware problem / how you could add lusca back to the upload route
https://github.com/expressjs/multer/issues/195#issuecomment-128820013

All 4 comments

I am also wondering if anyone has a solution for this

After some digging I found a solution for this. You need to override the csrf settings to blacklist your routes that use multipart/form-data. You could manually add lusca back in to those routes, the issue is the order in which the express middleware is being used.

nextApp
.prepare()
.then(() => {
  return nextAuthConfig();
})
.then(nextAuthOptions => {
  // Override lusca settings so we can allow multipart form submissions
  nextAuthOptions.csrf = { blacklist: ['/api/upload'] };
  return nextAuth(nextApp, nextAuthOptions);
})

Here's the full lusca configuration options:
https://github.com/krakenjs/lusca#luscacsrfoptions

And more info on the express middleware problem / how you could add lusca back to the upload route
https://github.com/expressjs/multer/issues/195#issuecomment-128820013

There is another solution, better and simplier, without using blacklist:

const _csrf = await NextAuth.csrfToken();
axios
      .post("/api/upload", data, {
        headers: { "Content-Type": "multipart/form-data", "x-csrf-token": _csrf },
      })
      .then((res) => {
           console.log("upload success");
      })
      .catch((err) => {
           console.log("upload fail ", err);
      });

Thanks for helping @jayarnielsen @nikitalk !

Sorry, CSRF token support was a pain for a lot of folks in version 1.0.

The good news is version 2.0 should be out soon as is much simpler.

It works without (but is compatible with!) Express and a simpler CSRF token verification system will be used, and only applied to authentication routes, so it won't muck up the rest of your app.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghoshnirmalya picture ghoshnirmalya  路  3Comments

alephart picture alephart  路  3Comments

simonbbyrne picture simonbbyrne  路  3Comments

alex-cory picture alex-cory  路  3Comments

benoror picture benoror  路  3Comments