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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 07:05:21