快速中间件

时间:2017-05-15 22:40:39

标签: node.js rest express authentication

我对此有点新鲜。我有使用Node.js和Express.js制作的REST API。有些路由有认证中间件。要使用这些路由,必须使用用户的身份验证令牌设置标头,并进行验证。我一直在使用本地存储的静态站点没有问题。我现在正在制作我的第一个动态网站(使用Express),对于某些路由,我有中间件加载显示页面所需的所有数据。现在我没有本地存储的帮助,如何访问和使用身份验证令牌?

编辑(澄清): 所以这是我的api路由之一,从数据库(mongoDB)获取所有事务。

app.get('/transactions', authenticate, (req, res) => {
  Transaction.find().then((transaction) => {
    res.send({transaction});
  }, (e) => {
    res.status(400).send();
  });
});

这是运行的身份验证中间件。

var authenticate = (req, res, next) => {
    var token = req.header('x-auth');

    User.findByToken(token).then((user) => {
        if (!user) {
          return Promise.reject();
        }
        req.user = user;
        req.token = token;
        next();
    }).catch((e) => {
        res.status(401).send();
    });
};

现在在我的快速网络服务器上,我有一个以下路线,我使用getTransactions来获取我的所有数据。 (我用把手显示)

router.get('/orders', getTransactions, (req, res) => {
  res.render('orders.hbs', {
    transaction: req.transactions.data.transaction
  });
});

这是中间件

var getTransactions = (req, res, next) => {
  axios.get('https://serene-wave-28270.herokuapp.com/transactions')
    .then((response) => {
      req.transactions = response;
      console.log(req.transactions.data.transaction);
      next();
    }).catch((e) => {
      console.log(e);
    })
}

因此,当我在不使用express作为网络服务器的情况下制作静态网站时,我只需让用户登录并将身份验证令牌保存在本地存储中。另外,我应该注意前两个块来自我的api,而后两个来自webserver,两者都是在Heroku上单独托管的。我不确定这是不是标准设计,所以我想我应该提一下。

2 个答案:

答案 0 :(得分:0)

关于你正在尝试做什么,你的问题中没有很多细节,但我可以在Express中解释你可以使用的一般概念:

Express的常用方案是最初对用户进行身份验证,然后设置一个会话cookie,指示用户已经过身份验证。由于cookie是由浏览器自动存储的,然后随着每个请求自动从浏览器发送到服务器,您将拥有该服务器可用于识别服务器端会话的cookie,然后您可以使用您想要的任何信息来自会话(用户标识或您在会话对象中存储的其他状态)在创建页面或响应该用户的API请求时。

NPM模块express-session会为您处理大部分工作,因为它会自动创建一个会话对象,一个会话cookie,并在每次请求时将两者挂钩。

另一方面,如果您在客户端中已经有一个身份验证令牌,并且您希望每次请求都自动将其传送到服务器,那么您可以将该身份验证令牌放入cookie并拥有服务器在每个请求的cookie中查找它。您甚至可以通过将cookie设置为HttpOnly来使其更安全,以便无法从客户端Javascript访问身份验证令牌(这不会影响服务器访问它的能力)。

答案 1 :(得分:0)

你的问题没有太多细节,但这里有一些想法。

你可以使用cookies(详见下面的@jfriend00)或使用请求的标题来检查有效的授权令牌(我在下面描述)

在Express中,您可以通过req.headers访问标题,这样您就可以在当前的中间件加载所有数据之前编写一个您将调用的中间件,以确保用户有权使用继续(调用next()来调用下一个中间件)或使用自定义错误类型标记身份验证错误(如果不是)(调用next(err)跳过所有其他中间件并跳转到错误中间件)< / p>

例如(假设您在某处定义了名为AuthorizationError的Error子类):

const express = require('express');
const AuthorizaztionError = require('<some path>');
const app = express();

function checkAuthTokenMiddleware(req, res, next) {
    if (req.headers && req.headers.authorization) {
        let token;
        const parts = req.headers.authorization.split(' ');
        if (parts.length == 2) {
            const [scheme, credentials] = parts;

            if (/^Bearer$/i.test(scheme)) { // or any other scheme you are using
                token = credentials;
            }

            if (token === undefined) {
                // access token - missing
                return next(new AuthorizationError(
                    "Invalid access token.", // error_description
                    "invalid_token" // error
                ));
            }
            // add something here to ensure the token is valid
            return next();
        }
    } else {
        // No authorization header => invalid credentials
        return next(new AuthorizationError(
            "Authorization header required.", // error_description
            "invalid_request" // error
        ));
    }

}

// Add this in your route declaration
app.use(
    "/auth/test",
    checkAuthTokenMiddleware,
    function(req, res, next) {
        // do something
    }
);

// this must come last
app.use(function errorMiddleware(err, req, res, next) {
    // return something
    if (err instanceof AuthenticationError) {
        // do something for example
        res.status(401).send(err.error_description);
    } else {
        // generic error handling, for example
        res.status(500).send("Error "+err);
    }
})

// ...