vercel / next.js

The React Framework
https://nextjs.org
MIT License
126.78k stars 26.95k forks source link

Can't use bcrypt in middleware #69002

Closed chriskuech closed 2 months ago

chriskuech commented 2 months ago

Link to the code that reproduces this issue

https://github.com/chriskuech/next-middleware-repro

To Reproduce

Repro 1: Simple repro

  1. npm run build

Repro 2: Experimental case + control case

  1. npm run dev
  2. Visit http://localhost:3000/skip-the-middleware
  3. Note that the page successfully loads--next correctly compiled the server module as a server module)
  4. Visit http://localhost:3000/run-the-middleware
  5. Note that the app fails to compile with webkit errors

Current vs. Expected behavior

Repro 1:

The build fails with a bunch of "Module Not Found"s and this build trace

Import trace for requested module:
./node_modules/@mapbox/node-pre-gyp/lib/node-pre-gyp.js
./node_modules/bcrypt/bcrypt.js
./src/lib/actions.ts
./src/middleware.ts

Repro 2

Expected: The middleware runs on the server and therefore successfully imports bcrypt Observed: The middleware appears to load bcrypt as a client module and fails to compile

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:46 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T6031
  Available memory (MB): 36864
  Available CPU cores: 14
Binaries:
  Node: 20.14.0
  npm: 10.7.0
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 14.2.5 // Latest available version is detected (14.2.5).
  eslint-config-next: 14.2.5
  react: 18.3.1
  react-dom: 18.3.1
  typescript: 5.5.4
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Middleware, Webpack

Which stage(s) are affected? (Select all that apply)

next dev (local), next build (local)

Additional context

Auth is cited in the next docs as a primary scenario for middlewares, so a little frustrating that bcrypt can't be used in middlewares.

More discussion: https://github.com/kelektiv/node.bcrypt.js/issues/979

areeburrub commented 2 months ago

Yes I am also having similar error.

Not only using bcrypt in middleware is producing error but also if it's being imported in a file and I use a exported server action from that file then also I am having the same error.

I am using a server action and the file which have all the action imports bcrypt for some other server action and still I am having error.

PS: I also want to usie bcrypt function in the middleware but I am just describing the fact that only imports are also throwing error.

> next dev

  ▲ Next.js 14.2.5
  - Local:        http://localhost:3000
  - Environments: .env.local, .env

 ✓ Starting...
 ✓ Ready in 24.1s
 ○ Compiling /src/middleware ...
 ⨯ ./node_modules/.pnpm/@mapbox+node-pre-gyp@1.0.11/node_modules/@mapbox/node-pre-gyp/lib/util/nw-pre-gyp/index.html
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <!doctype html>
| <html>
| <head>

Import trace for requested module:
./node_modules/.pnpm/@mapbox+node-pre-gyp@1.0.11/node_modules/@mapbox/node-pre-gyp/lib/util/nw-pre-gyp/index.html
./node_modules/.pnpm/@mapbox+node-pre-gyp@1.0.11/node_modules/@mapbox/node-pre-gyp/lib/ sync ^\.\/.*$
./node_modules/.pnpm/@mapbox+node-pre-gyp@1.0.11/node_modules/@mapbox/node-pre-gyp/lib/node-pre-gyp.js
./node_modules/.pnpm/bcrypt@5.1.1/node_modules/bcrypt/bcrypt.js
./src/utils/auth.ts
./src/_actions/auth.ts
 ⚠ ./node_modules/.pnpm/@mapbox+node-pre-gyp@1.0.11/node_modules/@mapbox/node-pre-gyp/lib/util/compile.js
Module not found: Can't resolve 'node-gyp' in 'E:\Projects\Spaceship CMS\spaceship-cms\node_modules\.pnpm\@mapbox+node-pre-gyp@1.0.11\node_modules\@mapbox\node-pre-gyp\lib\util'
areeburrub commented 2 months ago

I think I got the answer: https://nextjs.org/learn/dashboard-app/adding-authentication#password-hashing

Dragate commented 2 months ago

Had the same issue. Had to swap to bcryptjs that is compatible with the edge runtime.

chriskuech commented 2 months ago

@areeburrub my repro shows the middleware only indirectly importing bcrypt as that article recommends

chriskuech commented 2 months ago

@Dragate bcryptjs hasn't been updated in 8 years and appears to be abandonware, which is concerning for a security library, and bcrypt is recommended in @areeburrub 's link, so I think it's important that bcrypt works in nextjs.

areeburrub commented 2 months ago

There's nothing we can really do.

The problem is with the edge runtime as it doesn't support some NodeJs features even though it's a NodeJs runtime.

Theres always an alternate way to do things on the edge and if there is nothing to do then people create proxy api for the function to use in the edge.

I just moved the functions using bcrypt to another file and it works for me, as I wasn't using bcrypt in the middleware.

chriskuech commented 2 months ago

@areeburrub I understand the limitations of the edge runtime; however, I'm using NodeJS runtime so it seems like that does not apply.

I'm not sure what you mean by this, as this sounds like it matches my linked repro:

I just moved the functions using bcrypt to another file and it works for me, as I wasn't using bcrypt in the middleware.

Jayllyz commented 2 months ago

I'm using NodeJS runtime so it seems like that does not apply.

Middleware in Next.js are using edge runtime. https://nextjs.org/docs/app/building-your-application/routing/middleware#runtime

A good alternative to bcrypt which works for multiple runtime : jose