解析sessionToken在用户密码更新时被撤销

Parse sessionToken revoked on user password update

本文关键字:更新 密码 sessionToken 用户 解析      更新时间:2023-09-26

我的移动混合应用使用expressJS服务器作为后端,通过REST API代理对parse.com的请求。我还使用express通过SSO提供程序进行我自己的用户身份验证。我遵循本教程并修改了一些方法,以适应我自己的设置(不使用CloudCode,也不使用GitHub进行身份验证)。我还使用了今年早些时候(2015年3月?)的可撤销会话。从本质上讲,教程和我的认证方法可以归结为在远程后端(ExpressJS/CloudCode)上执行以下操作:

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

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

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

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

  4. 将sessionToken传递回客户端应用

这一切都很好,这似乎是与第三方认证提供商登录的"方法"。

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

新的增强会话博客文章提到,新的可撤销会话为每个设备提供了"唯一会话",但是从我的经验来看,这似乎不适用于从我的express后端通过REST API登录的用户。也许这个独特的会话只有在应用程序本身与解析通信时才能工作,因此能够传递一个installationId来区分不同的设备。

我已经在下面发布了我的认证代码,解析对象来自这个npm解析库

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在随后的登录?

哎呀,似乎我错过了设置页面上的一个开关:

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

我想这很简单;-)但是,我不认为我会在不同设备上获得独特的会话。