React项目用jsonwebtoken生成Token报错:Right-hand side of 'instanceof' is not an object
React项目中使用jsonwebtoken生成Token报错的解决方法
问题代码
用户在React组件中尝试生成JWT的代码如下:
import jwt from 'jsonwebtoken'; const MyForm = () => { const submitForm = (e) => { e.preventDefault(); const data = { name: 'name', email: 'email', subject: 'subject', message: 'message' }; const token = jwt.sign(data, 'qwerty'); console.log(token); } return( <form onSubmit={submitForm}> ... </form> ); } export default MyForm;
报错信息
运行时出现如下错误:
TypeError: Right-hand side of 'instanceof' is not an object push../node_modules/jsonwebtoken/sign.js.module.exports [as sign] ../node_modules/jsonwebtoken/sign.js:108 105 | return failure(new Error('secretOrPrivateKey must have a value')); 106 | } 107 | > 108 | if (secretOrPrivateKey != null && !(secretOrPrivateKey instanceof KeyObject)) { | ^ 109 | try { 110 | secretOrPrivateKey = createPrivateKey(secretOrPrivateKey) 111 | } catch (_) { View compiled submitEmail ../MyForm.js:22 19 | e.preventDefault(); 20 | 21 | const data = { name: 'name', email: 'email', subject: 'subject', message: 'message' }; > 22 | const token = jwt.sign(data, 'qwerty'); | ^ 23 | console.log(token) 24 | 25 |
错误原因
jsonwebtoken是专门为Node.js环境开发的库,它依赖Node.js内置crypto模块中的KeyObject类。而React项目运行在浏览器环境中,浏览器不存在KeyObject这个对象,代码执行到secretOrPrivateKey instanceof KeyObject时,右侧的KeyObject不是有效对象,因此抛出该错误。
另外需要注意:即便解决环境问题,在前端生成JWT也不安全——签名用的密钥会直接暴露在浏览器代码中,任何人都能拿到密钥伪造Token,完全失去JWT的安全意义。
解决方法
推荐方案:后端生成JWT
把生成Token的逻辑放到Node.js后端服务中,前端仅负责将表单数据发送到后端,由后端完成签名并返回Token。
示例代码:
- 后端(Express为例):
// server.js const express = require('express'); const jwt = require('jsonwebtoken'); const app = express(); app.use(express.json()); app.post('/generate-token', (req, res) => { const formData = req.body; // 可先验证表单数据合法性 const token = jwt.sign(formData, 'your-secret-key', { expiresIn: '1h' }); res.json({ token }); }); app.listen(3001, () => console.log('Server running on port 3001'));
- 前端修改:
// MyForm.jsx const MyForm = () => { const submitForm = async (e) => { e.preventDefault(); const data = { name: 'name', email: 'email', subject: 'subject', message: 'message' }; try { const response = await fetch('http://localhost:3001/generate-token', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data), }); const result = await response.json(); console.log(result.token); } catch (err) { console.error('请求失败:', err); } } return( <form onSubmit={submitForm}> ... </form> ); } export default MyForm;
非推荐方案:使用浏览器兼容的JWT库(仅用于测试或非敏感场景)
如果确实需要在前端生成(比如纯静态项目无后端),可以使用支持浏览器环境的JWT库,比如jsrsasign:
- 安装依赖:
npm install jsrsasign
- 前端代码修改:
import { KJUR } from 'jsrsasign'; const MyForm = () => { const submitForm = (e) => { e.preventDefault(); const data = { name: 'name', email: 'email', subject: 'subject', message: 'message' }; // 生成JWT const token = KJUR.jws.JWS.sign( 'HS256', // 签名算法 JSON.stringify({ alg: 'HS256', typ: 'JWT' }), // header data, // payload 'qwerty' // 密钥 ); console.log(token); } return( <form onSubmit={submitForm}> ... </form> ); } export default MyForm;
注意:此方案仅适用于非敏感场景,因为密钥会暴露在前端代码中,无法保证Token的安全性。
内容的提问来源于stack exchange,提问作者bcExpt1123
相关产品推荐
相关产品推荐

