Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I log out a user from the server in Meteor.js?

In my Meteor.js application, I want to let the administrator be able to forcibly log out users.

The use case is that my application is serving end-users, and the service is open whenever a super-user is logged in. If a super-user has forgotten to explicitly log out, the service will seem to be open for the end-users. If an administrator sees this, he/she should be able to forcibly log out the logged in user, and such render the service closed for the end-users.

Is this possible with Meteor.js? If so, how? Are there better/other approaches to this use case?

EDIT: Added some examples of remote logout I have tried, to clarify for @Akshat.

EXAMPLE 1(which does not work as I want):

In a logout method:

if (user.profile.role === ROLES.ADMIN) {
            Meteor
                .users
                .update({
                    _id: options.userId
                }, 
                { 
                    $set: { 
                        'services.resume.loginTokens' : [] 
                }});
        } else {
            throw new Meteor.Error(403, "You are not allowed to access this.");
        }

In my application.js:

var lastUserId;
Deps.autorun(function () {
    if(Meteor.user()) {
        if (Meteor.user().profile && Meteor.user().profile.firstName) {
            console.log("USER LOGGED IN");
            console.log("LENGTH LOGINTOKENS", 
                    Meteor
                        .user()
                        .services
                        .resume
                        .loginTokens.length); // This is always 1
            lastUserId = Meteor.user()._id;

            if (Meteor.user().services.resume.loginTokens.length === 0) {
                // This never fires, and thus the client does not know until
                // manually refreshed. Of course I could keep a forceLogOut-variable
                // as done in the next example.
                window.location.reload();
            }
        }
    } else {
        console.log("SOMETHING CHANGED IN METEOR.USER");
        if (lastUserId) {
            console.log("THE USER IS LOGGED OUT");
            Meteor.call('userLoggedOut',
            {
                userId: lastUserId
            });
            lastUserId = null;
        }
    }
});

EXAMPLE 2(this works as I want, when using only forceLogOut together with Meteor.logout() on the client side.):

In a logout method:

if (user.profile.role === ROLES.ADMIN) {
            Meteor
                .users
                .update({
                    _id: options.userId
                }, 
                { 
                    $set: { 
                        'services.resume.loginTokens' : [],
                        'profile.forceLogOut': true
                }});
        } else {
            throw new Meteor.Error(403, "You are not allowed to access this.");
        }

In my application.js:

var lastUserId;
Deps.autorun(function () {
    if(Meteor.user()) {
        if (Meteor.user().profile && Meteor.user().profile.firstName) {
            console.log("USER LOGGED IN");
            console.log("LENGTH LOGINTOKENS", 
                    Meteor
                        .user()
                        .services
                        .resume
                        .loginTokens.length); // This is always 1
            lastUserId = Meteor.user()._id;

            if (Meteor.user().profile.forceLogOut) {
                // Small example 1:
                // When logintokens have been set to [], and forceLogOut
                // is true, we need to reload the window to show the user
                // he is logged out.
                window.location.reload();
                // END Small example 1.

                // Small example 2:
                // When already keeping this variable, I might as well just use
                // this variable for logging the user out, and no resetting of
                // loginTokens are needed, or reloading the browser window.
                // This seems to me as the best way.
                console.log("FORCING LOGOUT");
                Meteor.logout();
                // END Small example 2.

                // And finally resetting the variable
                Meteor.call('resetForceLogOut',
                    {
                        userId: Meteor.user()._id
                    });
           }
        }
    } else {
        console.log("SOMETHING CHANGED IN METEOR.USER");
        if (lastUserId) {
            console.log("THE USER IS LOGGED OUT");
            Meteor.call('userLoggedOut',
            {
                userId: lastUserId
            });
            lastUserId = null;
        }
    }
});
like image 553
user2602152 Avatar asked Dec 11 '13 09:12

user2602152


People also ask

What is the meteor user () function for?

The Meteor Accounts system builds on top of the userId support in publish and methods . The core packages add the concept of user documents stored in the database, and additional packages add secure password authentication, integration with third party login services, and a pre-built user interface.

Which of the following user accounts packages are provided by the meteor developer group?

Here's a complete list of login providers for which Meteor actively maintains core packages: Facebook with accounts-facebook. Google with accounts-google. GitHub with accounts-github.

What is Meteor API?

What is Meteor? Meteor is a full-stack JavaScript platform for developing modern web and mobile applications. Meteor includes a key set of technologies for building connected-client reactive applications, a build tool, and a curated set of packages from the Node. js and general JavaScript community.


2 Answers

You have to delete all the loginTokens from the database. It will do it for all users with this query. You can customize the selector if you want to log out a smaller subset of users or exclude the current user.

Meteor.users.update({}, {$set : { "services.resume.loginTokens" : [] }}, {multi:true});

A couple of things:

  • This will log out all users including the current logged in user.
  • It only works on the server side
like image 106
Tarang Avatar answered Sep 30 '22 19:09

Tarang


Log out everyone but not the current user (you):

Meteor.users.update({
    _id: {
        $ne: Meteor.user()._id
    }
}, {
    $set: {
        "services.resume.loginTokens": []
    }
}, {
    multi: true
});
like image 21
cenk Avatar answered Sep 30 '22 19:09

cenk