The sessionToken is invalidated upon the user updating their password

My mobile hybrid app is connected to an expressJS server that acts as the backend for proxying requests to parse.com through the REST API. Additionally, I have implemented user authentication using express with a Single Sign-On (SSO) provider. Although I followed a tutorial similar to this one, I made modifications to suit my specific setup by not utilizing CloudCode and authenticating without GitHub. I am also taking advantage of the new Revokable Sessions feature introduced earlier this year (around March 2015?). Essentially, both the tutorial and my authentication method involve the following steps on a remote backend (ExpressJS / CloudCode):

Login As User to Obtain Session Token

  1. If the username does not already exist, create a new user and proceed

  2. Generate a random password for the user (updating the user's password using the masterKey)

  3. Log in as the user with the new password to generate the Parse sessionToken

  4. Send back the sessionToken to the client app

While this process works well and is commonly used for third-party authentication providers, there is an issue where each time a user logs in, a new sessionToken is created, essentially invalidating the old token. This results in users having to re-login if switching between devices or platforms. The blog post about enhanced sessions suggests that revokable sessions offer unique sessions per device; however, this functionality seems to be ineffective when users log in via the REST API from my express backend. It is possible that unique sessions only function properly when the app communicates directly with Parse, allowing for the passing of an installationId to differentiate between devices.

Below is the code snippet for my authentication, using the parse object from this npm parse library:

upsertUser function:

/**
 * This function checks if the user has logged in before.
 * If found, update their password to 'become' them and 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, creating new user');
        self.createNewUser(ssoData, deferred);

    } else {
        deferred.resolve();
    }

    });

    return deferred.promise;
}

createNewUser function:

/**
 * This function creates a Parse User with a random login and password, and
 * once completed, calls 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();
        }

    });

}

Any suggestions on how to prevent sessionTokens from being invalidated upon subsequent logins?

Answer №1

Oops, looks like there's a hidden option on the settings page that I overlooked:

Disable current session tokens when user updates password

Seems pretty straightforward, but I'm not sure if it will ensure unique sessions on all devices.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieving date from timestamp in a node.js environment

Can someone help me figure out how to display my timestamp as the date in the front end? I've tried multiple methods without success. Here is the code snippet: formulaire.addEventListener('submit', posteValidation); /** * Function to add a ...

Create a customizable Tree structure that includes checkboxes for each item and features drag

I am currently working on incorporating a Tree view with checkboxes and drag & drop functionality in Vue. However, I am unsure of where to begin. While I have successfully implemented checkboxes, I am struggling to figure out how to enable the feature whe ...

What are the best techniques for distinguishing the selected selector in jQuery?

$('#select_id1, #select_id2, #select_id3').change(function() { // Depending on which select element has changed, 'str' should be set accordingly. // For '#select_id1', 'str' should be equal to 'select_id ...

Loading Data in CodeMirror using XMLHttpRequest (XHR)

Is there any progress in loading the content into CodeMirror using XHR? ...

Troubleshooting HTTP requests in Angular JS when dealing with nested scopes

This particular question is derived from a previous answer found at this link. In my current scenario, I am attempting to initiate an http request where one of the data values that needs to be sent is represented in the view as {{selectedCountry.shippin ...

Comparing the use of input parameters to pass information in node.js versus the use

I'm grappling with the concept of when to inject a response into a function or call a function and retrieve something from it. Specifically in Node.js. Do functions in Node.js actually return data, or is it primarily about passing arguments and utili ...

Tips for fixing flickering tables and bringing the scrollbar back to the top in your DataTable Forge viewer

Presently, I am working with a DataTable that consists of 100 rows and is being set up using lists. The lists dynamically change based on the selected name from a drop down. To achieve this, I use: $("#datatable").remove(); this.datatable = new Au ...

What is the best way to create a seamless Asynchronous loop?

Adhering to the traditional REST standards, I have divided my resources into separate endpoints and calls. The primary focus here revolves around two main objects: List and Item (with a list containing items as well as additional associated data). For ins ...

Map does not provide zero padding for strings, whereas forEach does

Currently working on developing crypto tools, I encountered an issue while attempting to utilize the map function to reduce characters into a string. Strangely enough, one function works perfectly fine, while the other fails to 0 pad the string. What could ...

Trouble with reading from a newly generated file in a node.js program

Whenever I launch my results.html page, I generate a new JSON file and use express.static to allow access to the public folder files in the browser. Although my application is functioning properly, I find myself having to click the button multiple times f ...

Is there a way to adjust the transparency of individual words in text as you scroll down a page, similar to the effect on https://joincly

Is there a way to achieve a text filling effect on page scroll similar to the one found here: . The specific section reads: "Deepen customer relationships. Own the brand experience. Add high margin revenue. Manage it all in one place. Get back your pr ...

Learn how to manipulate data within a MongoDB database schema using Node.js and Mongoose: inserting, saving, and updating records

When inserting data into the MongoDB schema presented below, make sure that Employee name, Project name, and client name can be the same, but the employee ID must be unique. Duplicate entries are not allowed. var StatusSchema = new mongoose.Schema({ ...

Incorporate and interpret a custom JSON object within my Shopify Liquid theme

In an attempt to integrate custom data into my Shopify liquid theme, I stored a JSON file in the assets folder. My goal is to retrieve and parse this JSON object within a jQuery method from a JavaScript file also located in the assets folder. Despite try ...

The datatables button triggers an event twice

Whenever I click a button or tag in datatables, the modal opens twice and ajax runs twice. PS. I am using angular.js with datatables as a directive that is created by jQuery datatables, not the Angular datatables module. How can I solve this issue? Than ...

Enhance your Morris.js charts by incorporating detailed notes and annotations

Is there a way to include annotations in my morris.js charts? I couldn't find any information about this on their official website. I specifically need to add notes to certain dates. ...

Improprove the Express Router in a Node.js application

Is there a way to avoid repeating the isUserAuth and isAdminAuth middleware on each endpoint? Can I apply them just once so they work for all routes without having to specify them individually? const { createBranch, getAllBranch, getBranch } = require(&apo ...

The search for the "index" view in the views directory failed - Angular Universal SSR encounters errors with Firebase Cloud Functions

Currently, I am working through a tutorial on Server Side Rendering with Angular, Angular Universal, & Firebase 2021. The goal is to deploy my Angular universal project to Firebase hosting using Firebase functions. I managed to set up the emulator suc ...

Having trouble with the router when using identical modules, but there are no error messages

I am currently experimenting with the express router for a new project, and I have included my main app.js file below: "use strict"; const express = require("express"); const mongodb = require("mongodb"); const path = require("path"); const index = requi ...

Using express alone with mongoose will only provide the id field in the

The User Model: const mongoose = require('mongoose'); const Schema = mongoose.Schema; const UserSchema = new Schema({ email: { type: String, unique: true, required: true, trim: true }, username: { type: String, uni ...

Executing a single Function within the UseEffect Hook

Can anyone assist me with solving this code puzzle? I have a carousel element that includes icons for moving to the previous and next slides. Whenever these icons are clicked, a specific function needs to be triggered within the useEffect() hook. The spec ...