将用户会话从快速传递到反应状态

时间:2018-04-27 02:50:57

标签: mongodb reactjs express

我很难弄清楚如何将会话ID传递给react组件。所以基本上在用户登录后,它必须重定向到一个终点,并且我在该网站上访问的任何页面都必须在页面上提供会话ID,除非被销毁。

我设立了一个快速会议:

    // setup express session
    app.use(session({
      secret: 'this is your session',
      resave: true,
      saveUninitialized: false
    }));

// make userId available in templates
app.use(function (req, res, next){
  res.locals.currentUser = req.session.userId;
  next();
})

现在登录:

router.post('/', (req, res) => {
  const email = req.body.email;
  const password = req.body.password;

  if( email && password ){
    User.authenticate(email, password, function(err, user){
       if(err || !user){
         return res.status(404).json({error: true});
       } else {
         req.session.userId = user._id;
         res.redirect(303, '/main');
       }
    });
  }

上面的代码就是数据库中存在用户电子邮件和密码。如果是,那么它将设置会话ID。现在必须在页面上设置此会话ID:

现在在主页面的路由器上,我检查是否存在会话ID:

router.get('/main', (req, res) => {
  if(! req.session.userId ){
    return res.status(200);
  }

  User.findById(req.session.userId)
      .exec((err, user) => {
        if(err){
          console.log(err)
          res.redirect('/login');
        } else {
          res.redirect('/main');
        }
      })
});

如果它不存在,则必须重定向到同一页面,但如果是,则必须呈现相同的页面。

现在,对我来说最困难的部分是如何使会话ID可用于全局反应组件的状态?我的意思是我必须有一个全局变量来保存它所以我可以通过反应在整个前端页面中引用它吗?

import React, { Component } from 'react';
import axios from 'axios';

class Main extends Component {
  constructor(props) {
    super(props);
    this.state = {
      id: req.session.userId,
    };
  }

  componentDidMount() {
    axios
      .get(`/api/profile/${this.state.id}`)
      .then(response => {
       console.log(response)
      })
      .catch(error => {
        console.log(error);
      });
  }

  render() {
    return (
      <div>
        <h1>{this.state.id}</h1>
      </div>
    );
  }
}
export default UserAgenda;

我尝试使用console.log req.session.userId并返回undefined。我需要让它在我的状态中处于活动状态,就像一个可以被所有页面访问的全局变量,直到我销毁它。请帮忙!新手在这里。

1 个答案:

答案 0 :(得分:2)

似乎cookie可以用在你的用例中。

尝试将其添加到服务器代码而不是会话:

import cookieParser from 'cookie-parser';
app.use(cookieParser('secret'));

然后,在您验证用户设置ID cookie(而不是req.session.userId = user._id)之后:

res.cookie('id', user.id, { signed: true, httpOnly: true });

签名意味着它将被加密客户端,httpOnly意味着它将自动由浏览器传递(检查是否需要在axios中包含凭证中的标志)

在服务器上,您可以通过req.signedCookies.id

访问Cookie(用户ID)