如何使用 MongoDB + NodeJS Express 向 ReactJS React Router 和 Redux 添加登录身份验证和会话?

Posted

技术标签:

【中文标题】如何使用 MongoDB + NodeJS Express 向 ReactJS React Router 和 Redux 添加登录身份验证和会话?【英文标题】:How to add login authentication and session to ReactJS React Router and Redux with MongoDB + NodeJS Express? 【发布时间】:2017-01-08 14:40:35 【问题描述】:

我有一个 MongoDB + NodeJS Express 服务器,正在运行 Webpack,并且能够使用数据库凭据注册用户。我现在想在用户登录时添加身份验证和会话。我正在研究Passport.js,但似乎无法掌握如何将所有内容放在一起。

最好的方法是什么?任何示例和指导将不胜感激。

到目前为止,这些是我的设置。

对于服务器:

var express = require('express');
var path = require('path');
var config = require('../webpack.config.js');
var webpack = require('webpack');
var webpackDevMiddleware = require('webpack-dev-middleware');
var webpackHotMiddleware = require('webpack-hot-middleware');
var bodyParser = require('body-parser');
var MongoClient = require('mongodb').MongoClient;
var ObjectId = require('mongodb').ObjectID;

var app = express();
var db;

var compiler = webpack(config);

app.use(webpackDevMiddleware(compiler, noInfo: true, publicPath: config.output.publicPath));

app.use(webpackHotMiddleware(compiler));

app.use(express.static('dist'));

app.use(bodyParser.json());

app.post('/api/users/', function(req, res) 
  console.log('Req body', req.body);
  var newUser = req.body;
  db.collection('users').insertOne(newUser, function(err, result) 
    if(err) console.log(err);
    var newId = result.insertedId;

    db.collection('users').find(_id: newId).next(function(err, doc) 
      if(err) console.log(err);
      res.json(doc);
    )
  )
)

app.get('/', function (req, res) 
  res.sendFile(path.resolve('client/index.html'));
);

MongoClient.connect('mongodb://localhost/testdb', function(err, dbConnection) 
  if(err) console.log(err);

  db = dbConnection;
  var server = app.listen(3000, function() 
      var port = server.address().port;
      console.log("Started server at port", port);
  );
);

至于路由器(登录页面在Login,注册页面在Register呈现):

//react-router
render(
  <div>
    <Provider store=store>
      <Router history=hashHistory>
        <Route
          component =MainPage
          path='/'
        >
          <IndexRoute component=Login/>
          <Route
            component=Register path="Register"
          />
        </Route>
      </Router>
    </Provider>
  </div>,
  document.getElementById('app')
)

redux 中的 API POST 请求:

//How registered user's credentials are stored via action in redux
  registerUser(username, email, name, password) 
    console.log('Started registering request')
    var user = 
      username: username,
      email: email,
      name: name,
      password: password,
    

    var request = 
      method: 'POST',
      headers: 
        'Content-Type': 'application/json'
      ,
      body: JSON.stringify(user)
    

    console.log('Adding user: ', user)

    fetch(`http://localhost:3000/api/users`, request)
    .then(res => res.json())
    .then(user => 
      console.log(user);
      return user;
    )
    .catch(err => 
      console.log('Error is', err)
    )

    console.log('Ending registering request')
  ,

【问题讨论】:

使用client-sessions。可能更容易理解。加上它由 moz 制造。 @magreenberg 我知道所有这些中间件,但我不明白它们中的任何一个如何与我拥有的堆栈集成,尤其是 react-router。一个示例将比仅仅链接到另一个中间件真的有用。 【参考方案1】:

如果我很了解您需要让您的用户保持登录状态。我建议在您的用户登录 jwt 后使用 jwt 创建一个令牌并将此令牌存储到 localstorage.setItem(token) 中。

希望对你有帮助

【讨论】:

在本地存储中存储任何类型的授权令牌都是一个坏主意,因为 localStorage 在网站上没有任何类型的数据保护。令牌应该存储在带有 HttpOnly 标志的 cookie 中,以使令牌无法通过 javascript 访问,并且不受 XSS 和 Secure 标志的影响,以保证 cookie 仅通过 HTTPS 发送。【参考方案2】:

我推荐你使用这个 JWT 库,它与 expressJs 完美结合 https://www.npmjs.com/package/jsonwebtoken, 在您的用户登录后,您给主题一个 JWT 令牌,如下所示:

const token = jwt.sign(
   userId: user.userId, username: user.username ,
  yourFileWItchContainTheJwtString.jwtSecret,
   expiresIn: "1h" //keep connected for 1 hour
);

如果您想验证用户的 JWT 以保持他们的连接或给予他们一些授权,您可以使用以下方法进行验证:

jwtPayload = <any>jwt.verify(token, yourFileWItchContainTheJwtString.jwtSecret);
//save it in locals
 res.locals.jwtPayload = jwtPayload;

//从请求头部获取jwt令牌(对令牌做一些操作)

const token = <string>req.headers["auth"];

您可以查看文档https://www.npmjs.com/package/jsonwebtoken

【讨论】:

问题是关于会话而不是 JWT。使用 JWT 进行有关安全性的身份验证一直存在争议。

以上是关于如何使用 MongoDB + NodeJS Express 向 ReactJS React Router 和 Redux 添加登录身份验证和会话?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Id 使用 vuejs 编辑字段 mongodb、nodejs

如何使用nodeJS更新mongodb中的值?

如何使用 angular 和 nodejs 将 csv 数据转储到 mongoDB

如何使用 nodejs / express 将数据存储在 mongodb 中?

如何使用 MongoDB 和 Nodejs 创建用户角色/权限?

我如何使用 MongoDB 在 NodeJS 中编写以下 MySQL Select?