Javascript 使用用户名和;带有节点js、AngularJs和JWT的密码

Javascript 使用用户名和;带有节点js、AngularJs和JWT的密码,javascript,angularjs,node.js,jwt,Javascript,Angularjs,Node.js,Jwt,我正在创建一个productionangularJs应用程序 现在我创建了我的RESTFulAPI 这个API在登录时生成一个user对象,但是我不喜欢通过HTTP头发送passwordunhashed/unincrypted 要让您了解我的API: 登录时: var jwt = require('jwt-simple'); // Route: /login module.exports = function (express, sequelize, router) { va

我正在创建一个production
angularJs
应用程序

现在我创建了我的
RESTFul
API

这个
API
在登录时生成一个
user
对象,但是我不喜欢通过HTTP头发送
password
unhashed/unincrypted

要让您了解我的
API

登录时:

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

// Route: /login
module.exports = function (express, sequelize, router) {

    var DataTypes = require("sequelize");
    var crypto = require('crypto');

    var User = sequelize.define('user', {
            id: DataTypes.INTEGER,
            username: DataTypes.STRING,
            name: DataTypes.STRING,
            organization_id: DataTypes.INTEGER,
            type_id: DataTypes.INTEGER,
            division_id: DataTypes.INTEGER
        }, {
            freezeTableName: true,
            instanceMethods: {
                retrieveByNamePassword: function (username, onSuccess, onError) {
                    User.find({where: {username: username}}, {raw: true})
                        .then(onSuccess).catch(onError);
                }
            }
        }
    );

    router.route('/login')

        .post(function (req, res) {
            var user = User.build();

            var username = req.body.username || '';
            var password = req.body.password || '';

            if (username == '' || password == '') {
                res.status(401);
                res.json({
                    "status": 401,
                    "message": "Invalid credentials"
                });
                return;
            }

            user.retrieveByNamePassword(username, function (users) {
                if (users) {
                    // If authentication is success, we will generate a token
                    // and dispatch it to the client
                    res.json(genToken(users));
                    return;
                } else {
                    // If authentication fails, we send a 401 back
                    res.status(401);
                    res.json({
                        "status": 401,
                        "message": "Invalid credentials"
                    });
                    return;
                }
            }, function (error) {
                res.status(401);
                res.json({
                    "status": 401,
                    "message": "Invalid credentials"
                });
                return;
            });
        });

    var genToken = function(user) {
        var expires = expiresIn(7); // 7 days
        var token = jwt.encode({
            exp: expires,
            user_id: user.id,
            organization_id: user.organization_id,
            type_id: user.type_id,
            division_id: user.division_id

        }, require('./config/secret')());

        return {
            token: token,
            expires: expires,
            user: user
        };
    };

    var expiresIn = function(numDays) {
        var dateObj = new Date();
        return dateObj.setDate(dateObj.getDate() + numDays);
    };
正如您现在看到的(因为我还不确定如何处理它),我只是在寻找用户名,然后检查用户名是否存在


我的问题很简单,如何对密码进行加密,然后在密码到达API后进行验证?

JWT可以用于加密和非加密数据。但是,无论您是否对传输的信息进行加密,总会有一个签名过程,允许您在阅读之前验证您接收的信息是否未被篡改

对于通过URL在域之间传输登录状态的用例,我认为在JWT中根本不包含密码是最好的选择

以以下流程为例:

  • 通过HTTP将您的登录详细信息发布到domain1
  • 对用户进行身份验证。如果成功,请创建至少包含以下内容的JWT:

    2.1exp:到期时间(假设当前时间最多+10到15秒)

    2.2iat:令牌创建时间

    2.3电子邮件:用户的电子邮件地址

    2.4。不要包含用户密码(或任何其他敏感数据)

  • 使用URL中的JWT令牌将用户重定向到域2

  • 您的其他服务器/域可以检查JWT签名、iat和exp时间,以验证JWT未被篡改且有效
  • 如果全部有效,请将用户登录到其他域
  • 这是因为只要JWT数据进行验证,第二个域实际上就不需要知道用户的密码,因为domain1服务器已经验证了登录,只是告诉domain2接受它。只要您的JWT密钥保持完全保密,这应该是相当安全的。如果可能的话,我还鼓励使用自动方法定期在两台服务器上随机更改您的密钥

    注意:使用此方法,任何获得JWT的人都可以查看其中包含的数据,因此不要在其中传输任何机密或敏感信息


    注2:无论您在JWT的到期字段中设置了什么时间段,此方法都容易受到重播攻击。如果第三方可以在该时间段内获得该令牌,他们也可以使用该令牌作为该用户登录。因此,您必须将到期字段保持在尽可能低的水平,以降低发生这种情况的风险。

    这太晚了,但是您不能在使用crypt的用户模型之后添加一个钩子吗?(像这样:)


    所以我无法避免在HTTP上发布用户名和密码?如果我使用套接字连接,然后将元素推送到套接字上会怎么样?@MarcRasmussen我的回答主要是指使用JWT,只对数据进行签名以创建令牌。您可以选择在JWT中编码之前对发送的数据进行加密(使用公钥/私钥),然后在以后读取令牌时再次解密。这里提供了有关这方面的完整信息:无论您使用什么JWT库,都有一个简单的方法来实现这一点。注意-我回答了上面的问题,因为不发送敏感数据总比加密好。@Joel:你知道在更改密码/注销时使jwt无效的最佳做法是什么吗-
    // User model...
    },   {
    hooks: {
        beforeValidate: function() {
    
        },
        afterValidate: function(User) {
            User.hashword = bcrypt.hashSync(User.hashword, 10);
    
    
    
        },
        beforeCreate: function() {
    
        },
        afterCreate: function() {
    
        }
    }
    });