如何在Next.js中使用RSA私钥解密JWE令牌?
在Next.js中间件中解密JWE令牌并实现访问控制
以下是优化后的middleware.js实现,解决了原代码中的硬编码令牌、重复密钥初始化等问题,同时适配Next.js 13+的中间件规范:
import { NextResponse } from 'next/server'; import { jwtDecrypt, importPKCS8 } from 'jose'; import cookie from 'cookie'; // 预解析RSA私钥(仅初始化一次) const privateKey = await importPKCS8(`-----BEGIN RSA PRIVATE KEY----- // 替换为你的实际密钥内容 -----END RSA PRIVATE KEY-----`, 'RSA-OAEP'); export async function middleware(req) { // 从请求Cookie中获取JWE令牌(假设令牌存储在名为jwe_token的Cookie中) const cookies = cookie.parse(req.headers.get('cookie') || ''); const token = cookies.jwe_token; if (!token) { console.log('未找到令牌,正在重定向'); return NextResponse.redirect(new URL('https://www.example.com', req.url)); } try { // 解密JWE并解析负载,同时验证算法 const { payload } = await jwtDecrypt(token, privateKey, { algorithms: ['RSA-OAEP', 'A256GCM'] }); // 检查令牌过期时间 const currentTimestamp = Math.floor(Date.now() / 1000); if (payload.exp && payload.exp < currentTimestamp) { console.log('令牌已过期,正在重定向'); return NextResponse.redirect(new URL('https://www.example.com', req.url)); } console.log('令牌有效,允许访问'); return NextResponse.next(); } catch (err) { console.error('令牌验证失败:', err); return NextResponse.redirect(new URL('https://www.example.com', req.url)); } } // 指定中间件生效的路径(根据你的需求调整) export const config = { matcher: ['/protected/:path*'], };
关键改进说明
- 从Cookie获取令牌:替换原代码中的硬编码令牌,从请求的Cookie中读取实际的JWE令牌,符合真实业务场景
- 使用官方
jose库:替代node-jose,jose是标准化的JOSE实现,体积更小,对Next.js环境的兼容性更好 - 预解析私钥:将私钥解析逻辑放在中间件函数外部,避免每次请求都重复执行密钥初始化操作,提升性能
- 简化解密流程:使用
jwtDecrypt方法一步完成JWE解密和JWT负载解析,无需手动处理明文的JSON解析 - 规范重定向写法:Next.js 13+要求
NextResponse.redirect传入URL对象,确保重定向逻辑符合框架规范 - 明确生效路径:通过
config.matcher指定中间件仅对受保护的路径生效,避免不必要的性能开销
内容的提问来源于stack exchange,提问作者Sohaib Ashraf
相关产品推荐
相关产品推荐

