You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用jose验证JWT失败:Next.js/Clerk中间件报错排查

问题原因及解决方案

核心问题有两个:

  1. jwtVerify是异步函数,你没加await
    直接把jwtVerify的返回值赋值给decoded,得到的其实是一个Promise对象,这就是你看到Promise日志的原因。

  2. RS256算法需要CryptoKey类型的公钥,你传的是Uint8Array
    Clerk的公钥是PEM格式的字符串,不能直接用TextEncoder.encode转成Uint8Array,必须用jose提供的方法把PEM公钥解析成CryptoKey。

修复后的代码:

import { authMiddleware } from "@clerk/nextjs";
import { jwtVerify, importSPKI } from "jose";

export default authMiddleware({
  publicRoutes: ["/", "/contact", "/pricing", "/api/webhooks/user", "/api/reviews/add", "/api/user"],
  // 给afterAuth添加async关键字,支持await调用
  async afterAuth (auth, req, evt) {
    // 获取环境变量中的PEM格式公钥
    const publicKeyPem = process.env.CLERK_PUBLIC_KEY;
    // 将PEM公钥导入为RS256算法对应的CryptoKey
    const publicKey = await importSPKI(publicKeyPem, "RS256");
    
    // 用await获取jwtVerify的实际解析结果
    const decoded = await jwtVerify(
      "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJkZXYiOiJkdmJfMlpFZkVyUG91dHBuaFptQXZzdk0zMkVadkVhIiwiaWQiOiJjbGllbnRfMlpFZkpieUFQUXRWbVB4Q3R2SER4SE04a2tCIiwicm90YXRpbmdfdG9rZW4iOiJmaWNid25rZDE0aTVpNm5rZzJicjc1ODl5NWZqeGloemloZDk2dnprIn0.qURs213vHtEe_2DTmOVN8jCPCJhQfIIEjWLMIXgIVYs86U1J3P5BV9EHexjvXda416D4wHAFdxUhUzjKj42CNM4TYTrrsXRT4m_fMNq78NrvwMf7ge2tmcSYNf04c7gqInQzJMNiKILZbQXN0yxExZ1lBbPesg-ZCsx5HZ1544-g0yrcZvxu7HkSwIG56C3ITae51rtMj4lpxyYUxdR9MZ0JZ-HH2XlCT_F3BMDUn_IHNXj2IDF6gI-1kx3UWwYZ5uCyTipbsuOwgFCINFA2m8h3IM0jS9KXGLNrixaej9M0uDEcYkxVRvSwNKJfeHmnhJefYEk82192XpmXJDft8Q",
      publicKey
    );
    console.log(decoded);
  }
});

export const config = {
  matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"],
};

额外注意:

  • 确保process.env.CLERK_PUBLIC_KEY是完整的PEM格式字符串,包含-----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----以及中间的公钥内容。

内容的提问来源于stack exchange,提问作者Ethan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:02:32