javascript - 身份验证系统错误: Can't set headers after they are sent.

标签 javascript mysql node.js express ejs

我想编写一个带有 mysql 连接的小身份验证应用程序,但我总是收到此错误,但我需要这种方式。
如果客户端获取/admin(如果他不是管理员),我想发送响应,如果他是管理员,则应呈现 admin。

app.js

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
const admin = require("./routes/admin");
const session = require("express-session");
var app = express();
app.set("trust proxy", 1);
app.use(session({
  secret: "asdf",
  resave: false,
  cookie: {
    maxAge: 120000
  },
  saveUninitialized: false
}));
function checkIfLoggedin(req,res,next){
  if(!(req.originalUrl === "/") && !req.session.loggedIn){
    res.redirect('/');
    return;
  }
  next();
};


// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(checkIfLoggedin);
app.use('/', index);
app.use("/admin", admin);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});
module.exports = app;

index.js

var express = require('express');
var router = express.Router();
const bcrypt = require('bcrypt-nodejs');
var dbPassword;
import mysql from "mysql";
//
/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', {});
});
router.post('/', function(req,res,next) {
  console.log("1");
  const enteredUsername = req.body.username;
  const enteredPassword = req.body.password;
  const con = mysql.createConnection({
    host: "localhost",
    user: "user",
    password: "pass",
    database: "db"
  });
  con.query('SELECT * FROM users WHERE username = ?;', [`${enteredUsername}`], (error, results, fields) => {
    if (results.length > 0) {
      console.log("2");
      console.log(error);
      let dbPassword = results[0].password;
      bcrypt.compare(enteredPassword, dbPassword, (err,response) => {
        console.log(err);
        console.log(response);
        console.log("3");
        if (response == true) {
          req.session.user = {
            userId: results[0].userId,
            username: results[0].username,
            isAdmin: results[0].isAdmin,
          };
          req.session.loggedIn = true;
          console.log("file");
          if (req.session.user.isAdmin) {
            res.redirect("/admin");
          }
          else{
            res.redirect("/file/" + req.session.user.userId);
          }

        }
        else{
          req.session.loggedIn = false;

          console.log("false");
          res.send("Wrong password");
        }
      });
    }
    else{
      res.send("Wrong Data");
    }
  });
});
module.exports = router;

admin.js

var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
  if (!req.session.user.isAdmin) {
    res.send("Du bist kein Admin!");
  }
  res.render("admin");

});

module.exports = router;

索引.ejs

<!DOCTYPE html>
<html>
  <head>
    <title>Costufi</title>
      <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
      <link type="text/css" rel="stylesheet" href="stylesheets/materialize.min.css"  media="screen,projection"/>
  </head>
  <body>
    <main>
      <center>
        <div class="container">
          <div class="z-depth-2" style="display: inline-block; padding: 20px 50px 10px 50px; margin-top: 15%;">
            <form class="col s12" action="/" method="post">
              <div class="row">
                <h4>Login</h4>
                <div class="input-field col s12">
                  <input type="text" name="username" id="username" class="validate">
                  <label for="username">Username</label>
                </div>
              </div>
              <div class="row">
                <div class="input-field col s12">
                  <input type="password" name="password" id="password" class="validate">
                  <label for="password">PassworD</label>
                </div>
              </div>
              <div class="row">
                <button class="left btn waves-effect waves-light indigo darken-2" type="submit" name="send">Login
                  <i class="material-icons right">send</i>
              </div>
            </form>
          </div>
        </div>
      </center>
    </main>
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script type="text/javascript" src="js/materialize.min.js"></script>
  </body>
</html>

最佳答案

当您尝试向同一请求发送多个响应时,会导致此错误。我没有研究代码中的所有位置,但这里有一个明显的情况:

/* GET users listing. */
router.get('/', function(req, res, next) {
  if (!req.session.user.isAdmin) {
    res.send("Du bist kein Admin!");
  }
  res.render("admin");
});    

如果您的 if 测试为真,那么您最终会执行 res.send()res.render()res.render() 会触发警告,因为您已经在此连接上发送了响应,并且无法发送另一个响应。您应该将其更改为:

/* GET users listing. */
router.get('/', function(req, res, next) {
  if (!req.session.user.isAdmin) {
    res.send("Du bist kein Admin!");
  } else {
    res.render("admin");
  }
});    

关于javascript - 身份验证系统错误: Can't set headers after they are sent.,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48270822/

相关文章:

javascript - 特定按钮点击

javascript - 如何将 setTimeout() 与单例模块模式结合使用?

javascript - Python websockets onclose

mysql - 我应该为同一列创建 2 个索引来加速连接吗?

php - 让 localhost 在 mac OS X Yosemite 上运行

javascript - 在 "module"全局变量上运行 grunt-typescript 时,angular-mock 和 node.js 发生冲突

javascript - 有没有办法对网站上的每个页面进行截图?

c# - 是什么导致了 "Subquery returns more than 1 row"错误?

node.js - npm 安装在多域 git 存储库上失败

javascript - 如何同步滚动到 div 底部(聊天)