简体   繁体   English

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

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

I'm building a backend API with Node/Express, which get the data from a MongoDB. 我正在使用Node / Express构建一个后端API,它从MongoDB获取数据。 The front will be written in React. 前面将用React编写。

I would like to secure the communication client/server, but I don't know how I have to think about the process. 我想保护通信客户端/服务器,但我不知道如何考虑这个过程。

I see many tutorial about passport or JWT , but this is good for an user authentication. 我看到很多关于passportJWT教程,但这对于用户身份验证很有用。

I don't know if creating a token for every request based on the time (for example) is a good approach or it's too consuming for a web app. 我不知道是否根据时间(例如)为每个请求创建一个令牌是一种好方法,或者它对于一个Web应用来说太费劲了。

But my goal is to secure the data because even if the API is private you can easily find out the route and try to figure it out how to fake request with Postman or something else to scrap the data. 但我的目标是保护数据,因为即使API是私有的,您也可以轻松找到路线,并尝试弄清楚如何伪造请求与Postman或别的东西来废弃数据。

The accepted standard is to use a fixed API KEY. 接受的标准是使用固定的API KEY。 This peace of info should be a randomly generated string that you send in each request in the header. 这种信息的和平应该是一个随机生成的字符串,您可以在标题中的每个请求中发送。 Your server has to check the HTTP request each time to see if the API KEY is present in the header, and if it is, then it has to check against the stored value in the environment variable (never store the API KEY in code). 您的服务器每次都必须检查HTTP请求以查看标头中是否存在API KEY,如果是,则必须检查环境变量中的存储值(从不将API KEY存储在代码中)。

If the API KEY gets compromised, then you can easily update the env variable, and you are good again. 如果API KEY受到损害,那么您可以轻松更新env变量,并且您再次表现良好。

Now, this solution will be pointless without a HTTPS connection, because anyone will be able to sniff the traffic and see the API KEY. 现在,如果没有HTTPS连接,这个解决方案将毫无意义,因为任何人都可以嗅探流量并查看API KEY。 An encrypted connection is a must in this case. 在这种情况下,必须使用加密连接。

This approach is used by virtually every company that has a public API: Twitter, Facebook, Twilio, Google etc. 几乎所有拥有公共API的公司都使用这种方法:Twitter,Facebook,Twilio,Google等。

Google for example has an extra step where they give you a token that will expire, but this will be an over kill in your case: at least in the beginning. 例如谷歌有一个额外的步骤,他们会给你一个将过期的令牌,但这将是你的情况下的过度杀戮:至少在开始时。

The following code is an example of my implementation of a API KEY check 以下代码是我执行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()

});

You can check the whole file with the whole implementation hear . 您可以检查与整个执行整个文件听到

As I just finished the auth part of my AngularJS application. 我刚刚完成了AngularJS应用程序的auth部分。 The answer will be JWT and Passport , you should use the great technologies to protect your data / API. 答案是JWTPassport ,你应该使用伟大的技术来保护你的数据/ API。

If you use the JWT library, it will help you hold the http heads for authorization. 如果您使用JWT库,它将帮助您保存http头以进行授权。

Some of the code I used: 我使用的一些代码:

app.js app.js

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

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

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

login.js 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 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);
};

More Refs: 更多参考:

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

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