Node / Express - 客户端/服务器之间安全通信的良好方法

时间:2016-08-09 07:33:18

标签: node.js mongodb express encryption

我正在使用Node / Express构建后端API,它从MongoDB获取数据。前面将用React编写。

我想保护通信客户端/服务器,但我不知道如何考虑这个过程。

我看到很多关于passportJWT的教程,但这对于用户身份验证很有用。

我不知道是否根据时间(例如)为每个请求创建令牌是一种好方法,或者它对于网络应用来说太费力了。

但我的目标是确保数据的安全,因为即使API是私有的,您也可以轻松找到路线,并尝试弄清楚如何伪造请求与Postman或别的东西来废弃数据。

2 个答案:

答案 0 :(得分:5)

接受的标准是使用固定的API KEY。这种信息的和平应该是一个随机生成的字符串,您可以在标题中的每个请求中发送。您的服务器每次都必须检查HTTP请求以查看标头中是否存在API KEY,如果是,则必须检查环境变量中的存储值(从不将API KEY存储在代码中)。

如果API KEY遭到入侵,那么您可以轻松更新env变量,并且再次恢复正常。

现在,如果没有HTTPS连接,这个解决方案将毫无意义,因为任何人都可以嗅探流量并查看API KEY。在这种情况下,必须使用加密连接。

几乎所有拥有公共API的公司都使用这种方法:Twitter,Facebook,Twilio,Google等。

例如,谷歌有一个额外的步骤,他们会给你一个将过期的令牌,但在你的情况下这将是一个过度杀戮:至少在开始时。

以下代码是我实施API KEY检查的一个示例

app.use(function(req, res, next) {

    //
    //  1. Check if the APIKey is present
    //
    if(!req.headers.authorization)
    {
        return res.status(400).json(
            {
                message: "Missing APIKey.",
                description: "Unable to find the APIKey"
            }
        );
    }

    //
    //  2. Remove Basic from the beginning of the string
    //
    let noBasic = req.headers.authorization.replace('Basic ', '');

    //
    //  3. Convert from base64 to string
    //
    let b64toString = new Buffer(noBasic, 'base64').toString("utf8");

    //
    //  4. Remove the colon from the end of the string
    //
    let userAPIKey = b64toString.replace(':', '');

    //
    //  5. Check if the APIKey matches the one on the server side.
    //
    if(userAPIKey != process.env.API_KEY)
    {
        return res.status(400).json(
            {
                message: "APIKey don't match",
                description: "Make sure what you are sending is what is in your server."
            }
        );
    }

    //
    //  -> Go to the next stage
    //
    next()

});

您可以使用整个实施hear检查整个文件。

答案 1 :(得分:1)

我刚刚完成了 AngularJS 应用程序的auth部分。答案将是 JWT Passport ,您应该使用出色的技术来保护您的数据/ API。

如果您使用JWT库,它将帮助您保存http头以进行授权。

我使用的一些代码:

app.js

var jwt = require('express-jwt');

var auth = jwt({
    secret: config.jwt.secret,
    userProperty: 'payload'
});

app.use('/api/secret', auth, apiSecretRoutes);

login.js

module.exports.login = function (req, res) {
    if (!req.body.username || !req.body.password) {
        return tools.sendJSONresponse(res, 400, {
            message: 'All fields required!'
        });
    }

    passport.authenticate('local', function (err, user, info) {
        var token;
        if (err) {
            return tools.sendJSONresponse(res, 404, err);
        }

        if (user) {
            token = user.generateJwt();
            return tools.sendJSONresponse(res, 200, {
                ok: true,
                message: 'welcome ' + user.name,
                token: token
            });
        } else {
            return tools.sendJSONresponse(res, 400, info);
        }
    })(req, res);
};

user.js的

userSchema.methods.generateJwt = function() {
    var expiryDays = 1;
    var expiry = new Date();
    expiry.setDate(expiry.getDate() + expiryDays);

    return jwt.sign({
        _id: this._id,
        username: this.username,
        name: this.name,
        exp: parseInt(expiry.getTime() / 1000)
    }, config.jwt.secret);
};

更多参考: