Node.js+PostgreSQL报text=bigint操作符不存在错误及Token校验咨询
问题解决建议
一、解决"operator does not exist: text = bigint"报错
这个错误源于直接拼接SQL语句导致的类型不匹配,同时还存在SQL注入风险,核心解决方法是使用参数化查询:
错误原因分析
你当前直接把id、cid、newemail拼接进SQL字符串,比如如果id是从req.body获取的字符串类型,拼接后SQL会变成WHERE id = '123'(带引号)或WHERE id = 123(实际是字符串值),而如果数据库中id字段是bigint类型,PostgreSQL无法直接对text和bigint进行比较,因此抛出该错误。
修改后的代码
const bcrypt = require("bcrypt"); const client = require("../configs/database"); const jwt = require("jsonwebtoken"); exports.updateemail = async (req, res) => { const { id, newemail, cid } = req.body; // 使用参数化查询,$1、$2、$3为占位符,对应后续参数数组 const query = "UPDATE users SET email = $1 WHERE id = $2 AND cid = $3"; try { // 参数数组会自动匹配占位符,PostgreSQL负责类型转换 const result = await client.query(query, [newemail, id, cid]); // 注意不要覆盖请求传入的res对象 res.status(200).send({ message: 'Success' }); } catch (err) { console.log(err.stack); res.status(500).send({ error: err.message }); } };
额外注意事项
- 避免用
const res = await client.query(...),会覆盖原本的响应对象res,改用result这类变量名。 - 参数化查询会自动处理字符串引号和类型匹配,彻底解决类型不匹配问题。
二、检查Token是否存在及验证
Token通常通过请求头的Authorization字段传递,格式为Bearer <Token字符串>,检查和验证流程如下:
1. 基础检查与验证逻辑
exports.updateemail = async (req, res) => { // 从请求头获取Authorization字段 const authHeader = req.headers.authorization; // 检查Token是否存在且格式正确 if (!authHeader || !authHeader.startsWith('Bearer ')) { return res.status(401).send({ message: 'Token不存在或格式错误' }); } // 提取纯Token内容(移除前缀"Bearer ") const token = authHeader.split(' ')[1]; // 验证Token有效性 try { const decoded = jwt.verify(token, process.env.JWT_SECRET); // 可选:验证Token中的用户信息与请求参数是否匹配,防止越权 if (decoded.id !== id) { return res.status(403).send({ message: '无权限修改此用户' }); } } catch (err) { return res.status(403).send({ message: 'Token无效' }); } // 后续更新逻辑 const { id, newemail, cid } = req.body; const query = "UPDATE users SET email = $1 WHERE id = $2 AND cid = $3"; try { const result = await client.query(query, [newemail, id, cid]); res.status(200).send({ message: 'Success' }); } catch (err) { console.log(err.stack); res.status(500).send({ error: err.message }); } };
2. 最佳实践:抽成中间件
将Token验证逻辑抽为独立中间件,可在多个接口复用:
// authMiddleware.js const jwt = require("jsonwebtoken"); const verifyToken = (req, res, next) => { const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith('Bearer ')) { return res.status(401).send({ message: 'Token不存在或格式错误' }); } const token = authHeader.split(' ')[1]; try { const decoded = jwt.verify(token, process.env.JWT_SECRET); req.user = decoded; // 将解码后的用户信息挂载到req对象 next(); // 继续执行后续接口逻辑 } catch (err) { return res.status(403).send({ message: 'Token无效' }); } }; module.exports = verifyToken;
在路由中使用中间件:
const express = require('express'); const router = express.Router(); const verifyToken = require('./authMiddleware'); const userController = require('./userController'); // 仅允许携带有效Token的请求访问此接口 router.put('/updateemail', verifyToken, userController.updateemail); module.exports = router;
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

