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

JWT+Session认证部署后仅客户端登录失败,请求排查内部错误

本地正常但虚拟主机部署后客户端登录失败问题

问题现象

本地环境中,基于JWT+Session实现的管理员/客户端认证功能运行正常,但部署到虚拟主机后出现内部服务器错误:仅管理员登录可正常跳转至admin.html,客户端登录无法跳转至client.html。

服务器报错信息

Checking whether to disconnect long-running connections for process 70002, application VBJ (production) at Function process_params 
App 70002 output:     at /home/c2100699c/VBJ/app.js:229:5
App 70002 output:     at isValidCredentials (/home/c2100699c/VBJ/app.js:244:14)

相关代码

app.js 核心代码

// JWT认证中间件
function verifyToken(req, res, next) {
  const token = req.cookies.token || '';
  jwt.verify(token, 'secret', function (err, decoded) {
    if (err) {
      return res.redirect('/login.html');
    } else {
      req.decoded = decoded;
      next();
    }
  });
}

// 登录接口
app.post('/auth', function (req, res) {
  const username = req.body.username;
  const password = req.body.password;
  const email = req.body.email;
  console.log('Request data:', username, password, email);

  // 管理员硬编码认证
  if ((username === '***********' && email === '*****************') && password === '*********') {
    const token = jwt.sign({
      username,
      email,
      role: 'admin'
    }, 'secret', {
      expiresIn: '1h'
    });
    res.cookie('token', token, {
      httpOnly: true
    });
    return res.redirect('/admin.html');
  } else {
    // 普通用户数据库认证
    isValidCredentials(username, password, email, function (valid, isAdmin) {
      if (valid) {
        const role = isAdmin ? 'admin' : 'client';
        const token = jwt.sign({
          username,
          email,
          role
        }, 'secret', {
          expiresIn: '1h'
        });
        res.cookie('token', token, {
          httpOnly: true
        });
        return res.redirect('/client.html');
      } else {
        return res.redirect('/login.html');
      }
    });
  }
});

// 验证用户凭证
function isValidCredentials(username, password, email, callback) {
  const query = 'SELECT * FROM users WHERE username = ? AND password = ? AND email = ? AND administrateur = 0';
  connection.query(query, [username, password, email], function (error, results, fields) {
    if (error)
      throw error;
    if (results.length > 0) {
      const isAdmin = results[0].administrateur === 1;
      callback(true, isAdmin);
    } else {
      callback(false, false);
    }
  });
}

// 管理员页面路由
app.get('/admin', verifyToken, function (req, res) {
  if (req.session.loggedin) {
    res.sendFile(__dirname + '/admin.html');
  } else {
    res.send('请登录后访问此页面');
  }
  res.end();
});

// 客户端页面路由
app.get('/client', verifyToken, function (req, res) {
  if (req.session.loggedin) {
    res.sendFile(__dirname + '/client.html');
  } else {
    res.send('请登录后访问此页面');
  }
  res.end();
});

login.js 前端代码

const loginForm = document.getElementById('login');
submit.addEventListener('click', function (event) {
  event.preventDefault();
  login();
});

function login() {
  const username = document.getElementById('username').value;
  const password = document.getElementById('password').value;
  const email = document.getElementById('emailRegister').value;

  fetch('/auth', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      username,
      password,
      email
    })
  })
  .then(res => {
    console.log('Response status:', res.status);
    console.log('Response headers:', res.headers);
    return res.json();
  })
  .then(data => {
    console.log('Response data:', data);
    if (data.userType === 'administrateur') {
      window.location.href = '/admin.html';
    } else if (data.userType === 'client') {
      window.location.href = '/client.html';
    } else {
      document.querySelector("#message2").innerText = "账号、邮箱或密码错误";
    }
  })
  .catch(error => {
    console.log('Error:', error);
  });
}

解决建议

  • 修复SQL查询逻辑矛盾:isValidCredentials函数中SQL查询添加了administrateur = 0条件,但后续又判断results[0].administrateur === 1,逻辑完全冲突。去掉查询中的AND administrateur = 0条件,确保查询结果能正确匹配用户的管理员状态。
  • 处理数据库连接异常:虚拟主机的数据库配置(地址、端口、权限)可能与本地不同,检查connection对象的生产环境配置是否正确;同时在isValidCredentials中添加错误捕获,避免直接抛出异常导致服务器崩溃,改为通过回调传递错误状态。
  • 统一认证机制:当前同时混用JWT和Session,但登录接口仅设置了JWT Cookie,未初始化Session的loggedin状态,导致客户端登录后访问/client路由时被判定为未登录。要么用JWT的req.decoded.role判断权限,去掉Session相关逻辑;要么在登录成功时同步设置req.session.loggedin = true。
  • 适配前端跳转逻辑:后端登录接口返回的是重定向,但前端fetch会自动跟随重定向并尝试解析HTML为JSON,触发错误。可修改后端返回JSON数据由前端负责跳转,或在前端判断响应的重定向状态直接跳转。

内容的提问来源于stack exchange,提问作者Miguel Vidal bravo jandia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 23:34:57