Qwik City中用Vercel-Edge适配器哈希密码遇部署问题求助
解决Qwik City Vercel Edge部署时argon2-browser的打包错误
问题原因
argon2-browser是为浏览器环境设计的库,它依赖Node.js内置的path模块,但Vercel Edge Runtime不支持Node.js内置模块,导致Rollup打包时出错。
解决方案
方案1:替换为兼容Edge Runtime的密码哈希库(推荐)
选择纯JS或Wasm实现、无Node内置模块依赖的argon2库,比如@noble/hashes(轻量、安全、兼容所有环境)。
步骤:
- 卸载
argon2-browser
npm uninstall argon2-browser
- 安装
@noble/hashes
npm install @noble/hashes
- 修改server$函数代码:
import { argon2id, randomBytes } from '@noble/hashes/argon2'; import { hex } from '@noble/hashes/utils'; export const authSignup = server$(async function ( firstName: string, lastName: string, email: string, password: string, passwordConf: string, username: string, ) { // ... 你的其他验证逻辑 const name = firstName.trim() + ' ' + lastName.trim(); // 生成16字节的随机盐(不要硬编码盐,每个用户使用独立盐) const salt = randomBytes(16); // 执行argon2id哈希(推荐使用argon2id算法,平衡安全性和性能) const hashBytes = argon2id(password, salt, { timeCost: 3, // 迭代次数 memoryCost: 65536,// 内存占用(KB) parallelism: 1, // 并行度 length: 32 // 哈希输出长度(字节) }); // 将哈希和盐转为十六进制字符串,用冒号分隔便于存储和后续验证 const hash = `${hex(hashBytes)}:${hex(salt)}`; // ... 后续将用户信息和哈希存入数据库的逻辑 });
方案2:尝试配置ssr.noExternal(不推荐)
如果一定要保留argon2-browser,可以在Vite配置中标记该库不需要外部化,但由于Edge Runtime不支持path模块,大概率仍会运行失败。在vite.config.ts中添加:
export default defineConfig(() => { return { plugins: [qwikCity(), qwikVite(), vercelEdge()], ssr: { noExternal: ['argon2-browser'], }, }; });
方案3:使用Web Crypto API的PBKDF2(备选)
如果不想额外安装库,可以使用Edge Runtime原生支持的Web Crypto API实现PBKDF2哈希(安全性略低于argon2,但符合标准):
export const authSignup = server$(async function ( firstName: string, lastName: string, email: string, password: string, passwordConf: string, username: string, ) { // ... 你的其他验证逻辑 const name = firstName.trim() + ' ' + lastName.trim(); // 生成16字节随机盐 const salt = crypto.getRandomValues(new Uint8Array(16)); // 导入密码并生成PBKDF2哈希 const key = await crypto.subtle.importKey( 'raw', new TextEncoder().encode(password), { name: 'PBKDF2' }, false, ['deriveBits'] ); const hashBuffer = await crypto.subtle.deriveBits( { name: 'PBKDF2', salt: salt, iterations: 100000, // 迭代次数,越高越安全 hash: 'SHA-256' }, key, 256 // 哈希输出长度(256位=32字节) ); // 将哈希和盐转为十六进制字符串 const hashHex = Array.from(new Uint8Array(hashBuffer)) .map(b => b.toString(16).padStart(2, '0')) .join(''); const saltHex = Array.from(salt) .map(b => b.toString(16).padStart(2, '0')) .join(''); const hash = `${hashHex}:${saltHex}`; // ... 后续存储逻辑 });
重要提示
- 绝对不要硬编码盐(如你代码中的
somesalt),必须为每个用户生成独立的随机盐,否则会严重降低密码哈希的安全性。 - 优先选择argon2算法(如方案1),它是当前密码哈希的推荐标准,比PBKDF2、bcrypt等更安全。
内容的提问来源于stack exchange,提问作者PiWizard3852
相关产品推荐
相关产品推荐

