繁体   English   中英

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

[英]Node/Express - Good approach to secure communication between client/server

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

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

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

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

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

接受的标准是使用固定的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()

});

您可以检查与整个执行整个文件听到

我刚刚完成了AngularJS应用程序的auth部分。 答案是JWTPassport ,你应该使用伟大的技术来保护你的数据/ 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);
};

更多参考:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM