2013-12-11 12 views
10

Nella mia applicazione Meteor.js, voglio consentire all'amministratore di disconnettere forzatamente gli utenti.Come posso disconnettere un utente dal server in Meteor.js?

Il caso di utilizzo è che la mia applicazione è al servizio degli utenti finali e il servizio è aperto ogni volta che un superutente ha effettuato l'accesso. Se un super utente ha dimenticato di disconnettersi esplicitamente, il servizio sembrerà essere aperto per gli utenti finali. Se un amministratore lo vede, dovrebbe essere in grado di disconnettere forzatamente l'utente che ha effettuato l'accesso e tale render deve essere chiuso per gli utenti finali.

Ciò è possibile con Meteor.js? Se é cosi, come? Ci sono migliori/altri approcci a questo caso d'uso?

MODIFICA: sono stati aggiunti alcuni esempi di disconnessione remota che ho provato, per chiarire per @Akshat.

ESEMPIO 1 (che non funziona come voglio):

In un metodo di logout:

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."); 
     } 

Nei miei 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; 
     } 
    } 
}); 

ESEMPIO 2 (questo funziona come voglio, quando uso solo forceLogOut insieme a Meteor.logout() sul lato client.):

In un logout Metodo:

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."); 
     } 

Nei miei 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; 
     } 
    } 
}); 

risposta

22

È necessario eliminare tutti i loginTokens dal database. Lo farà per tutti gli utenti con questa query. È possibile personalizzare il selettore se si desidera disconnettere un sottoinsieme più piccolo di utenti o escludere l'utente corrente.

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

Un paio di cose:

  • Questo registrerà tutti gli utenti, tra cui l'attuale utente connesso.
  • Funziona solo sul lato server
+0

Cercherò questo in una volta! Grazie per la pronta risposta. Questo è documentato ovunque, btw? – user2602152

+2

Non penso che sia documentato ma Meteor usa i valori all'interno di 'loginTokens' per identificare gli utenti che hanno effettuato l'accesso. Quindi senza di loro gli utenti vengono disconnessi dal momento che tutto è reattivo – Akshat

+0

A volte funziona come un incantesimo, e la vista utente è rerenderizzata e l'utente viene reindirizzato alla pagina di accesso. Ma altre volte l'utente è ancora in grado di muoversi all'interno della "area riservata". Devo fare un aggiornamento per l'utente per vedere che è disconnesso. Come posso risolvere questo? – user2602152

2

Esci tutti, ma non l'utente corrente (voi):

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