【问题标题】:req.session is not storing datareq.session 不存储数据
【发布时间】:2018-02-06 08:25:26
【问题描述】:

我正在尝试实现一个登录系统,用户可以在其中注册到网站,然后使用他的帐户登录。一旦用户登录,他可以编辑他的个人信息。

为了检查用户是否登录,我尝试将req.session.isLoggedIn 设置为true,然后检查该值是否为真以访问网站的某些区域。问题是,就在我登录后,我打印了req.session 的值,我看到我刚刚设置的值,但是在那之后,当我尝试在另一条路线上检查req.session.isLoggedIn 的值时,我没有得到任何值。

这是我的代码:

const express = require('express');
const app = express();
var { Client } = require('pg');
var bcrypt = require('bcrypt');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var cors = require('cors');
var path = require('path');
var session = require('express-session');
var url = require("url");


app.use(cors());
app.use(express.static(path.join(__dirname, 'client/build')));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 600000000 }}))

const client = new Client({
  user: 'xxxxxxxxxxxxx',
  host: 'xxxxxxxxxxxxx',
  password: 'xxxxxxxxxxxxxxx',
  database: 'xxxxxxxxxxxxxx',
  port: 5432,
  ssl: true
})
client.connect();

/*Rutas*/

/*Seleccionar huellas pertenecientas a una cierta categoria*/
app.get('/api/huellas/:categoria', (req, res) => {
  client.query('SELECT * FROM huellas WHERE categoria = $1 AND activo = TRUE', [req.params.categoria], (err, query) => {
    if (err) {
      console.log(err.stack);
    } else {
      res.json(query.rows);
    }
  });
});

/*Listar todas las huellas*/
app.get('/api/mostrarHuellas', function(req, res, next) {
  client.query('SELECT * FROM huellas', (err, query) => {
    if (err) {
      console.log(err.stack);
    } else {
      res.json(query.rows);
    }
  });
});

app.get('/api/buscarHuellas/', function(req, res) {
  console.log(req);
  console.log("nombre: " + req.query.nombre + " categoria: " + req.query.categoria + " estado: " + req.query.estado);
  client.query('SELECT * FROM huellas WHERE (nombre = $1 AND categoria = $2 AND estado =  $3) AND activo = TRUE', [req.query.nombre, req.query.categoria, req.query.estado], (err, query) => {
    if (err) {
      console.log(err.stack);
    } else {
      res.json(query.rows);
    }
  });
});

app.post("/api/registro", function(req, res) {
  var email = req.body.email;
  var password = bcrypt.hashSync(req.body.password, 10);
  client.query('INSERT INTO usuarios(email, password, huella) VALUES ($1, $2, $3)', [email, password, req.body.huella], function(err, result) {
    if(err) {
      //console.log(err.stack);
      res.json(err);
    }
    else {
      console.log('row inserted');
      res.json("ok");
    }
  });
});

app.post("/api/login", function(req, res) {
  client.query('SELECT * FROM usuarios WHERE email = $1', [req.body.email], (err, query) => {
    if (err) {
      console.log(err.stack);
    } else {
      if(bcrypt.compareSync(req.body.password, query.rows[0].password)){
        req.session.isLoggedIn = true;

        console.log(req.session);
        res.json("ok");
      }
      else{
        res.json("clave invalida");
      }
      res.end();
    }
  });
});

app.get("/api/logout", function(req, res) {
  req.session.destroy();
});

app.get("/api/sessions", function(req, res){
  console.log(req.session);
  if(req.session.isLoggedIn) {
    console.log("logged in!");
  }
});


const port = process.env.PORT || 5000;
app.listen(port);

当我访问/api/login/时,我在终端收到这个输出,我可以看到isLoggedIn:

    Session {
  cookie: 
   { path: '/',
     _expires: 2017-09-05T00:29:19.786Z,
     originalMaxAge: 600000000,
     httpOnly: true },
  isLoggedIn: true }

但在那之后,当我访问 /api/sessions/ 时,我会收到以下输出:

Session {
  cookie: 
   { path: '/',
     _expires: 2017-09-05T00:29:21.451Z,
     originalMaxAge: 599999999,
     httpOnly: true } }

我正在使用 Nodejs 和 Expressjs。另外,我正在提供一些存储在/client/build 中的静态文件,它们工作正常。

提前致谢!

编辑:

这是我的句柄登录方法的样子,我正在使用 react 和 react-router 4:

handleSubmit(event){
   event.preventDefault();
   fetch('/api/login', {
   method: 'post',
   headers: {'Content-Type':'application/json'},
   body: JSON.stringify({
     "email": document.getElementById("email").value,
     "password": document.getElementById("pwd").value
   })
   })
     .then(response => response.json())
     .then(res => {
        switch (res) {
          case "clave invalida":
            alert("clave invalida");
            break;
          case "ok":
            alert("sesion iniciada");
            this.props.history.push("/");
            break;
         default:
           alert("Error. Contacte a un administrador");
           break;
       }
     })
     .catch(err => console.log(err));
  };

【问题讨论】:

    标签: node.js reactjs session express


    【解决方案1】:

    您需要在想要保存它们时发送带有res 对象的cookie。这是我的代码,它可以工作。看看吧。

    app.use(session({
      secret: 'keyboard cat',
      resave: true,
      saveUninitialized: true,
    }))    
    
    
    app.get("/", function(req, res){
      if(req.session.views){
        req.session.views++;
      }else{
        req.session.views = 1;
      }
      res.status(200).send(req.session);
    })
    
    
    app.get("/checkerPage", function(req, res){
      console.log(req.session); //it logs the correct data.
      res.send("whatever");
    })
    
    //post req
    
    app.post("/post", function(req, res){
      req.session.user = "myname";
      res.send(req.session);
      console.log(req.session);
    });
    

    我的索引html

    <form action="/post" method="post">
      <input type="text" name="myName" value="">
      <input type="submit" name="" value="submit">
    </form>
    

    【讨论】:

    • 我尝试了您的解决方案,使用 GET 和 POST 路由,但只能使用 GET 路由。你知道为什么会发生这种情况吗? res.status(200).send(req.session) 在条件块内,它不应该给出异步/问题或类似的东西。我发布了我的方法,以及我收到的输出here
    • 你确定吗?这个对我有用。你能检查更新吗? @Julio
    • 也许尝试删除status(200)
    • 我一直在尝试不同的东西,只有当我在表单中使用action="link/to/the/api" 时它才有效。但是当我在 onSubmit 事件中使用我的 AJAX 调用时,它不起作用,req.session.isLoggedIn 没有被存储。 Here 是我的带有 handleSubmit 方法的 React 组件。直接使用 action="link-to-api" 的问题是我收到一个带有 cookie 信息的空白屏幕,我无法处理(或者至少,我不知道如何按照我在pastebin 我要离开这里)。提前感谢@turmuka!
    • 我刚刚解决了我的问题,我发布了解决方案。无论如何,我要感谢你花时间帮助我解决我的问题,我从你的回答中学到了一些新东西。
    【解决方案2】:

    好吧,我刚刚找到了解决问题的方法。我使用了@ytibrewala here 发布的解决方案和@nlawson here 发表的评论。这就是我所做的:

    显然,默认情况下fetch方法不发送cookies,所以需要在AJAX调用中设置credentials参数,我是这样设置的:

    AJAX 调用

      handleSubmit(event){
       event.preventDefault();
       fetch('http://localhost:5000/api/login', {
       method: 'post',
       credentials: 'include',
       headers: {'Content-Type':'application/json'},
       body: JSON.stringify({
         "email": document.getElementById("email").value,
         "password": document.getElementById("pwd").value
       })
       })
         .then(response => response.json())
         .then(res => {
           console.log(res);
           if(res.isLoggedIn){
             alert("Signed in");
             this.props.history.push("/hueprint");
           }
           else{
             alert("Invalid user or password");
           }
         })
         .catch(err => console.log(err));
      };

    我使用了include,因为我使用的不是同一个来源。有关credentials 参数接受的值的更多信息,请参见here

    然后,我在浏览器中遇到了 CORS 问题,所以我在后端的 index.js 文件上更改了这个:

    index.js

    app.use(cors({credentials: true, origin: true}));
    

    现在,每次我在我的网站中使用我的 handleSubmit 方法时,我都会检查打印req.session 的测试路线,我看到我的isLoggedIn 参数设置正确。

    我离开我的路线,给那些想看的人:

    app.post("/api/login", function(req, res) {
      client.query('SELECT * FROM usuarios WHERE email = $1', [req.body.email], (err, query) => {
        if (err) {
          console.log(err.stack);
        }
        else {
          if(bcrypt.compareSync(req.body.password, query.rows[0].password)){
            console.log("password matches");
            req.session.isLoggedIn = true;
            req.session.save();
            res.send(req.session);
          }
          else{
            console.log("password doesn't match");
            req.session.isLoggedIn = false;
            req.session.save();
            res.send(req.session);
          }
        }
      });
    });

    【讨论】:

    • 嗯,哇,我也从您那里学到了新东西,感谢您的出色回应!现在检查developer.mozilla.org/en-US/docs/Web/HTTP/Headers/… 这个页面,凭据必须是true 页面才能使用数据:) 干得好,
    • 谢谢。我整天都在寻找这个答案。使用credentials: 'include' 和fetch() 请求并将{credentials: true, origin: true} 添加到cors() 调用选项解决了request.session 数据为undefined。
    猜你喜欢
    • 2014-04-26
    • 2012-11-19
    • 1970-01-01
    • 2019-07-17
    • 2019-12-26
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 2014-03-05
    相关资源
    最近更新 更多