用户密码更新

时间:2015-08-21 01:24:36

标签: javascript session authentication express parse-platform

我的移动混合应用程序使用expressJS服务器作为后端,通过REST API代理对parse.com的请求。我也使用express用于我自己的SSO提供商的用户身份验证。我跟着this tutorial并修改了一些方法以适应我自己的设置(不使用CloudCode,也不使用GitHub进行身份验证)。我也在使用今年早些时候(2015年3月发布的)新推出的Revokable Sessions?基本上,教程和我的auth方法可以归结为在远程后端(ExpressJS / CloudCode)上执行以下操作:

以用户身份登录以获取会话令牌

  1. 如果用户名尚不存在,请创建新用户,然后继续

  2. 为用户创建一个新的随机密码(使用masterKey更新用户密码)

  3. 使用新密码,以用户身份登录以生成Parse sessionToken

  4. 将sessionToken传回客户端应用

  5. 这一切都运行正常,似乎是使用第三方身份验证提供程序登录的“方法”。

    问题是每次我的用户登录时,都会重新创建sessionToken(因为它会破坏旧的并创建一个新的令牌)。我可以在dataBrowser中看到这个,因为会话objectId是不同的。此外,主要问题是我的用户可能已登录到其他设备或Web应用程序,并且基本上每次用户切换设备时,会话令牌在其他设备上无效。返回该设备则需要再次登录。

    new enhance session博客文章提到新的可撤销会话为每台设备提供“唯一会话”,但根据我的经验,对于从我的快速后端通过REST API登录的用户来说这似乎不起作用。也许这个唯一的会话只有在应用程序本身正在与解析通信时才能工作,因此能够通过installationId来区分不同的设备。

    我在下面发布了我的身份验证代码,解析对象来自此npm parse library

    upsertUser函数:

    /**
     * This function checks to see if this user has logged in before.
     * If the user is found, update their password in order to 'become' them and then return
     * the user's Parse session token.  If not found, createNewUser
     */
    exports.upsertUser = function(ssoData, deferred) {
    
        var userCreated = (typeof deferred != "undefined") ? true : false;
        var deferred = deferred || q.defer();
        var query = {
            where: {username: ssoData.uid.trim()}
        };
    
        // set masterKey
        parse.masterKey = parseConfig.MASTER_KEY;
    
        // find existing user by username
        parse.getUsers( query, function (err, res, body, success) {
    
        if ( body.length ) {
            var userId = body[0].objectId;
            var username = body[0].username;
            var password = new Buffer(24);
            _.times(24, function (i) {
                password.set(i, _.random(0, 255));
            });
            password = password.toString('base64');
    
            parse.updateUser(userId, {password: password}, function (err, res, body, success) {
                if ( typeof body.updatedAt != 'undefined' ) {
                    console.log('user update at: ', body.updatedAt);
                    parse.loginUser(username, password, function (err, res, body, success) {
                        deferred.resolve( body.sessionToken );
                    });
    
                }
    
            });
    
        } else if ( userCreated === false ) {
            console.log('object not found, create new user');
            self.createNewUser(ssoData, deferred);
    
        } else {
            deferred.resolve();
        }
    
        });
    
        return deferred.promise;
    }
    

    createNewUser函数:

    /**
     * This function creates a Parse User with a random login and password, and
     * Once completed, this will return upsertUser.  
     */
    exports.createNewUser = function(ssoData, deferred) {
    
        // Generate a random username and password.
        var password = new Buffer(24);
        _.times(24, function(i) {
            password.set(i, _.random(0, 255));
        });
    
        var newUser = {
            username: ssoData.uid,
            password: password.toString('base64'),
        };
    
        // Sign up the new User
        parse.createUser(newUser, function(err, res, body, success) {
    
            if (err) {
                console.log('new parse user err', err)
            }
    
            if (typeof body.sessionToken != "undefined") {
    
                self.upsertUser(ssoData, deferred);
    
            } else {
                deferred.resolve();
            }
    
        });
    
    }
    

    我有什么想法可以避免在后续登录时使sessionTokens失效?

1 个答案:

答案 0 :(得分:4)

拍摄,似乎我错过了设置页面上的切换:

  

用户更改密码时撤消现有会话令牌

简单,因为我猜;-)但是,我不认为我会在各种设备上获得独特的会话。