Nextjs构建失败,因为_middleware.ts中存在jsonwebtoken

yeotifhr  于 2023-01-13  发布在  其他
关注(0)|答案(3)|浏览(259)

我希望得到一些关于Vercel部署的帮助。我创建了一个_middleware.ts文件,用于检查用户cookie中的JWT。

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { JwtPayload, verify } from 'jsonwebtoken'

export async function middleware(req: NextRequest) {
  let response = NextResponse.next()
  const url = req.nextUrl.clone()

  const token = req.cookies['allow-list']

  if (!token || token === 'deleted') {
    return response 
  }

  try {
    const decodedToken = verify(
      token,
      process.env.TOKEN_SECRET as string
    ) as JwtPayload
  } catch (e) {}

  return response
}

但是,正因为如此,当我尝试构建我的项目时,我得到了以下错误:“中间件页面/_middleware中不允许动态代码评估(例如,”eval“、”new Function“)”。有解决方法吗?当我在本地运行它时,它可以工作。

[22:59:29.409] Cloning github.com/dimitriborgers/test (Branch: master, Commit: efc1977)
[22:59:30.051] Cloning completed: 642.161ms
[22:59:30.427] Installing build runtime...
[22:59:34.350] Build runtime installed: 3.924s
[22:59:35.048] Looking up build cache...
[22:59:35.297] Build Cache not found
[22:59:35.503] Installing dependencies...
[22:59:35.507] Detected `package-lock.json` generated by npm 7...
[22:59:54.367] 
[22:59:54.367] added 519 packages in 19s
[22:59:54.367] 
[22:59:54.367] 97 packages are looking for funding
[22:59:54.367]   run `npm fund` for details
[22:59:54.386] Detected Next.js version: 12.1.0
[22:59:54.392] Detected `package-lock.json` generated by npm 7...
[22:59:54.392] Running "npm run build"
[22:59:54.673] 
[22:59:54.673] > build
[22:59:54.673] > next build
[22:59:54.673] 
[22:59:55.312] Attention: Next.js now collects completely anonymous telemetry regarding usage.
[22:59:55.312] This information is used to shape Next.js' roadmap and prioritize features.
[22:59:55.312] You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
[22:59:55.312] https://nextjs.org/telemetry
[22:59:55.313] 
[22:59:55.351] info  - Checking validity of types...
[22:59:58.776] warn  - No ESLint configuration detected. Run next lint to begin setup
[22:59:58.781] info  - Creating an optimized production build...
[22:59:58.786] warn  - using beta Middleware (not covered by semver) - https://nextjs.org/docs/messages/beta-middleware
[23:00:22.847] Failed to compile.
[23:00:22.847] 
[23:00:22.847] ./node_modules/function-bind/implementation.js
[23:00:22.847] Dynamic Code Evaluation (e. g. 'eval', 'new Function') not allowed in Middleware pages/_middleware
[23:00:22.848] 
[23:00:22.848] Import trace for requested module:
[23:00:22.848] ./node_modules/function-bind/index.js
[23:00:22.848] ./node_modules/call-bind/index.js
[23:00:22.848] ./node_modules/call-bind/callBound.js
[23:00:22.848] ./node_modules/which-typed-array/index.js
[23:00:22.848] ./node_modules/util/support/types.js
[23:00:22.848] ./node_modules/util/util.js
[23:00:22.848] ./node_modules/jws/lib/sign-stream.js
[23:00:22.849] ./node_modules/jws/index.js
[23:00:22.849] ./node_modules/jsonwebtoken/decode.js
[23:00:22.849] ./node_modules/jsonwebtoken/index.js
[23:00:22.849] ./pages/_middleware.ts
[23:00:22.849] 
[23:00:22.849] ./node_modules/get-intrinsic/index.js
[23:00:22.849] Dynamic Code Evaluation (e. g. 'eval', 'new Function') not allowed in Middleware pages/_middleware
[23:00:22.849] 
[23:00:22.849] Import trace for requested module:
[23:00:22.849] ./node_modules/call-bind/callBound.js
[23:00:22.849] ./node_modules/which-typed-array/index.js
[23:00:22.849] ./node_modules/util/support/types.js
[23:00:22.849] ./node_modules/util/util.js
[23:00:22.849] ./node_modules/jws/lib/sign-stream.js
[23:00:22.849] ./node_modules/jws/index.js
[23:00:22.850] ./node_modules/jsonwebtoken/decode.js
[23:00:22.850] ./node_modules/jsonwebtoken/index.js
[23:00:22.850] ./pages/_middleware.ts
[23:00:22.850] 
[23:00:22.850] ./node_modules/has/src/index.js
[23:00:22.850] Dynamic Code Evaluation (e. g. 'eval', 'new Function') not allowed in Middleware pages/_middleware
[23:00:22.850] 
[23:00:22.850] Import trace for requested module:
[23:00:22.850] ./node_modules/get-intrinsic/index.js
[23:00:22.850] ./node_modules/call-bind/callBound.js
[23:00:22.850] ./node_modules/which-typed-array/index.js
[23:00:22.850] ./node_modules/util/support/types.js
[23:00:22.850] ./node_modules/util/util.js
[23:00:22.850] ./node_modules/jws/lib/sign-stream.js
[23:00:22.850] ./node_modules/jws/index.js
[23:00:22.850] ./node_modules/jsonwebtoken/decode.js
[23:00:22.851] ./node_modules/jsonwebtoken/index.js
[23:00:22.851] ./pages/_middleware.ts
[23:00:22.851] 
[23:00:22.851] ./node_modules/is-generator-function/index.js
[23:00:22.851] Dynamic Code Evaluation (e. g. 'eval', 'new Function') not allowed in Middleware pages/_middleware
[23:00:22.851] 
[23:00:22.851] Import trace for requested module:
[23:00:22.851] ./node_modules/util/support/types.js
[23:00:22.852] ./node_modules/util/util.js
[23:00:22.852] ./node_modules/jws/lib/sign-stream.js
[23:00:22.852] ./node_modules/jws/index.js
[23:00:22.852] ./node_modules/jsonwebtoken/decode.js
[23:00:22.852] ./node_modules/jsonwebtoken/index.js
[23:00:22.852] ./pages/_middleware.ts
[23:00:22.853] 
[23:00:22.853] ./node_modules/next/dist/compiled/vm-browserify/index.js
[23:00:22.854] Dynamic Code Evaluation (e. g. 'eval', 'new Function') not allowed in Middleware pages/_middleware
[23:00:22.854] 
[23:00:22.854] Import trace for requested module:
[23:00:22.854] ./node_modules/jwa/index.js
[23:00:22.854] ./node_modules/jws/lib/sign-stream.js
[23:00:22.854] ./node_modules/jws/index.js
[23:00:22.854] ./node_modules/jsonwebtoken/decode.js
[23:00:22.855] ./node_modules/jsonwebtoken/index.js
[23:00:22.855] ./pages/_middleware.ts
[23:00:22.855] 
[23:00:22.855] 
[23:00:22.855] > Build failed because of webpack errors
[23:00:22.886] Error: Command "npm run build" exited with 1
ercv8c1e

ercv8c1e1#

由于中间件运行时基于浏览器而不是服务器,因此在该位置不允许eval。此外,中间件运行时允许的最大持续时间是1.5秒。因此,我们不能依赖于从Edge函数的另一个服务器获取验证。
我已经完全删除了jsonwebtoken库的使用,并使用jose来克服这个问题,并保持代码库的简化,代码在浏览器和服务器运行时都能工作,使我们能够在中间件层本身验证用户。

**签署 JWT **

import * as jose from 'jose';

const jwtToken = await new jose.SignJWT({ userId: `your-data` })
                        .setProtectedHeader({ alg: 'HS256' })
                        .setIssuedAt()
                        .setExpirationTime('30d')
                        .sign(new TextEncoder().encode(`secret-key-phrase`));

正在验证JWT

这在中间件上工作,没有任何问题(Vercel上的Edge Function)。

import * as jose from 'jose';

try {
    const { payload: jwtData } = await jose.jwtVerify(
        jwtToken, new TextEncoder().encode(`secret-key-phrase`)
    );
    // jwtData.uid => `your-data`
} catch (error) {
    console.log(error);
    // JWT validation failed or token is invalid
}
0s7z1bwu

0s7z1bwu2#

使用@tsndr/cloudflare-worker-jwt库代替jsonwebtoken可以工作。

mxg2im7a

mxg2im7a3#

不支持大多数本机nodejs API
edge runtime
下面是下一个正式示例jwt middleware source此代码示例使用josejose repo

import { type NextRequest, NextResponse } from 'next/server'
import { verifyAuth } from '@lib/auth'

export const config = {
  matcher: [ '/api/protected', '/protected' ],
}

export async function middleware(req: NextRequest) {
  // validate the user is authenticated
  const verifiedToken = await verifyAuth(req).catch((err) => {
    console.error(err.message)
  })

  if (!verifiedToken) {
    // if this an API request, respond with JSON
    if (req.nextUrl.pathname.startsWith('/api/')) {
      return new NextResponse(
        JSON.stringify({ 'error': { message: 'authentication required' } }),
        { status: 401 });
    }
    // otherwise, redirect to the set token page
    else {
      return NextResponse.redirect(new URL('/', req.url))
    }
  }
}

相关问题