bibliothèques d'authentification utilisateur pour le nœud.js?

Existe-t-il des bibliothèques d'authentification utilisateur existantes pour le nœud.js? En particulier, je cherche quelque chose qui peut faire l'authentification par mot de passe pour un utilisateur (en utilisant un backend personnalisé auth DB), et associer cet utilisateur à une session.

Avant d'écrire une bibliothèque auth, je pensais que je verrais si les gens connaissaient les bibliothèques existantes. Impossible de trouver quelque chose d'évident via une recherche google.

-Shreyas

269
demandé sur shreddd 2010-08-17 02:44:10

12 réponses

Si vous recherchez un cadre d'authentification pour Connect ou Express, Passport mérite d'être étudié: https://github.com/jaredhanson/passport

(divulgation: je suis le développeur de passeport)

J'ai développé Passport après avoir étudié à la fois connect-auth et everyauth. Bien qu'ils soient tous deux excellents modules, ils ne répondaient pas à mes besoins. Je voulais quelque chose qui était plus léger et discret.

Passport est décomposé en modules séparés, de sorte que vous pouvez choisir d'utiliser uniquement ce dont vous avez besoin (OAuth, seulement si nécessaire). Passport ne monte pas non plus de routes dans votre application, ce qui vous donne la flexibilité de décider quand et où vous voulez l'authentification, et des crochets pour contrôler ce qui se passe lorsque l'authentification réussit ou échoue.

Par exemple, voici le processus en deux étapes pour configurer l'authentification basée sur un formulaire (nom d'utilisateur et mot de passe):

passport.use(new LocalStrategy(
  function(username, password, done) {
    // Find the user from your DB (MongoDB, CouchDB, other...)
    User.findOne({ username: username, password: password }, function (err, user) {
      done(err, user);
    });
  }
));

app.post('/login', 
  passport.authenticate('local', { failureRedirect: '/login' }),
  function(req, res) {
    // Authentication successful. Redirect home.
    res.redirect('/');
  });

Des stratégies supplémentaires sont disponibles pour l'authentification via Facebook, Twitter, etc. Personnaliser les stratégies peuvent être branchées, si nécessaire.

229
répondu Jared Hanson 2011-10-24 17:34:18

Session + Si

Je suppose que la raison pour laquelle vous n'avez pas trouvé beaucoup de bonnes bibliothèques est que l'utilisation d'une bibliothèque pour l'authentification est la plupart du temps trop conçue.

Ce que vous cherchez est juste un classeur de session:) une session avec:

if login and user == xxx and pwd == xxx 
   then store an authenticated=true into the session 
if logout destroy session

C'est tout.


Je ne suis pas d'accord avec votre conclusion que le plugin connect-auth est la voie à suivre.

J'utilise aussi connect {[15] } mais je n'utilise pas connect-auth pour deux raisons:

  1. Pauses IMHO connect-auth l'architecture oignon-anneau très puissante et facile à lire de connect. Un no-go - mon avis :). Vous pouvez trouver un très bon et court article sur la façon dont connect fonctionne et l'idée de l'anneau d'oignon ici .

  2. Si vous - comme écrit-voulez juste utiliser une connexion de base ou http avec une base de données ou un fichier. Connect-auth est beaucoup trop grand. C'est plus pour des choses comme OAuth 1.0, OAuth 2.0 & Co


Une authentification très simple avec connect

(c'est compléter. Exécutez-le simplement pour les tests, mais si vous voulez l'utiliser en production, assurez-vous d'utiliser https) (Et pour être conforme au principe REST, vous devez utiliser une POST-Request au lieu D'une GET-Request B / C vous changez d'état:)

var connect = require('connect');
var urlparser = require('url');

var authCheck = function (req, res, next) {
    url = req.urlp = urlparser.parse(req.url, true);

    // ####
    // Logout
    if ( url.pathname == "/logout" ) {
      req.session.destroy();
    }

    // ####
    // Is User already validated?
    if (req.session && req.session.auth == true) {
      next(); // stop here and pass to the next onion ring of connect
      return;
    }

    // ########
    // Auth - Replace this example with your Database, Auth-File or other things
    // If Database, you need a Async callback...
    if ( url.pathname == "/login" && 
         url.query.name == "max" && 
         url.query.pwd == "herewego"  ) {
      req.session.auth = true;
      next();
      return;
    }

    // ####
    // This user is not authorized. Stop talking to him.
    res.writeHead(403);
    res.end('Sorry you are not authorized.\n\nFor a login use: /login?name=max&pwd=herewego');
    return;
}

var helloWorldContent = function (req, res, next) {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('authorized. Walk around :) or use /logout to leave\n\nYou are currently at '+req.urlp.pathname);
}

var server = connect.createServer(
      connect.logger({ format: ':method :url' }),
      connect.cookieParser(),
      connect.session({ secret: 'foobar' }),
      connect.bodyParser(),
      authCheck,
      helloWorldContent
);

server.listen(3000);

NOTE

J'ai écrit cette déclaration il y a plus d'un an et n'ai actuellement aucun projet de nœud actif. Il y a donc peut-être des changements D'API dans Express. S " il Vous Plaît ajouter un commentaire si je dois changer quoi que ce soit.

88
répondu nivoc 2012-05-07 16:20:09

On dirait que le plugin connect-auth du middleware connect est exactement ce dont j'ai besoin: http://wiki.github.com/ciaranj/connect-auth/creating-a-form-based-strategy

J'utilise express [ http://expressjs.com ] donc, le plugin connect s'intègre très bien puisque express est sous-classé (OK-prototypé) à partir de connect

26
répondu shreddd 2010-10-12 23:05:52

Je cherchais essentiellement la même chose. Plus précisément, je voulais ce qui suit:

  1. à utiliser express.js, qui enveloppe la capacité middleware de Connect
  2. authentification"basée sur un formulaire"
  3. contrôle granulaire sur les routes authentifiées
  4. un back-end de base de données pour les utilisateurs / mots de passe
  5. Utiliser les sessions

Ce que j'ai fini par faire était de créer ma propre fonction middleware check_auth que je passe comme argument à chaque route que je veux authentifier. check_auth vérifie simplement la session et si l'utilisateur n'est pas connecté, puis les redirige vers la page de connexion, comme ceci:

function check_auth(req, res, next) {

  //  if the user isn't logged in, redirect them to a login page
  if(!req.session.login) {
    res.redirect("/login");
    return; // the buck stops here... we do not call next(), because
            // we don't want to proceed; instead we want to show a login page
  }

  //  the user is logged in, so call next()
  next();
}

Ensuite, pour chaque route, je m'assure que cette fonction est passée en tant que middleware. Par exemple:

app.get('/tasks', check_auth, function(req, res) {
    // snip
});

Enfin, nous devons réellement gérer le processus de connexion. C'est simple:

app.get('/login', function(req, res) {
  res.render("login", {layout:false});
});

app.post('/login', function(req, res) {

  // here, I'm using mongoose.js to search for the user in mongodb
  var user_query = UserModel.findOne({email:req.body.email}, function(err, user){
    if(err) {
      res.render("login", {layout:false, locals:{ error:err } });
      return;
    }

    if(!user || user.password != req.body.password) {
      res.render("login",
        {layout:false,
          locals:{ error:"Invalid login!", email:req.body.email }
        }
      );
    } else {
      // successful login; store the session info
      req.session.login = req.body.email;
      res.redirect("/");
    }
  });
});

En tout cas, cette approche a surtout été conçue pour être flexible et simple. Je suis sûr qu'il existe de nombreuses façons de l'améliorer. Si vous en avez, j'aimerais beaucoup votre rétroaction.

EDIT: ceci est un exemple simplifié. Dans un système de production, vous ne voudriez jamais stocker et comparer les mots de passe en texte brut. Comme le souligne un commentateur, il existe des bibliothèques qui peuvent aider à gérer la sécurité des mots de passe.

14
répondu Tom 2012-09-24 17:04:54

Jetez également un oeil à everyauth Si vous voulez une intégration de connexion de réseau tiers/social.

13
répondu Peter Lyons 2011-09-08 15:50:34

Voici un code pour l'authentification de base d'un de mes projets. Je l'utilise contre CouchDB avec et un cache de données d'authentification supplémentaire, mais j'ai dépouillé ce code.

Enroulez une méthode d'authentification autour de la gestion des requêtes et fournissez un deuxième rappel pour une authentification sans succès. Le rappel de succès obtiendra le nom d'utilisateur en tant que paramètre supplémentaire. N'oubliez pas de gérer correctement les demandes avec des informations d'identification erronées ou manquantes dans le rappel d'échec:

/**
 * Authenticate a request against this authentication instance.
 * 
 * @param request
 * @param failureCallback
 * @param successCallback
 * @return
 */
Auth.prototype.authenticate = function(request, failureCallback, successCallback)
{
    var requestUsername = "";
    var requestPassword = "";
    if (!request.headers['authorization'])
    {
        failureCallback();
    }
    else
    {
        var auth = this._decodeBase64(request.headers['authorization']);
        if (auth)
        {
            requestUsername = auth.username;
            requestPassword = auth.password;
        }
        else
        {
            failureCallback();
        }
    }


    //TODO: Query your database (don't forget to do so async)


    db.query( function(result)
    {
        if (result.username == requestUsername && result.password == requestPassword)
        {
            successCallback(requestUsername);
        }
        else
        {
            failureCallback();
        }
    });

};


/**
 * Internal method for extracting username and password out of a Basic
 * Authentication header field.
 * 
 * @param headerValue
 * @return
 */
Auth.prototype._decodeBase64 = function(headerValue)
{
    var value;
    if (value = headerValue.match("^Basic\\s([A-Za-z0-9+/=]+)$"))
    {
        var auth = (new Buffer(value[1] || "", "base64")).toString("ascii");
        return {
            username : auth.slice(0, auth.indexOf(':')),
            password : auth.slice(auth.indexOf(':') + 1, auth.length)
        };
    }
    else
    {
        return null;
    }

};
7
répondu b_erb 2010-08-18 07:59:38

Quelques années ont passé et j'aimerais vous présenter ma solution d'authentification pour Express. Il s'appelle Lockit . Vous pouvez trouver le projet sur GitHub et une courte intro à mon blog.

Alors, quelles sont les différences avec les solutions existantes?

  • facile à utiliser: configurer votre DB, npm installer, require('lockit'), lockit(app), fait
  • itinéraires déjà intégré (/inscription /login, /oublié mot de passe, etc.)
  • Vues déjà intégrées (basées sur Bootstrap mais vous pouvez facilement utiliser vos propres vues)
  • Il prend en charge la communication JSON pour votre AngularJS / Ember.js unique page Applications
  • Il ne supporte pas OAuth et OpenID. Seulement username et password.
  • Il fonctionne avec plusieurs bases de données (CouchDB, MongoDB, SQL) prêtes à l'emploi
  • Il a des tests (je n'ai trouvé aucun test pour les cloisons sèches)
  • , il est activement maintenu (par rapport à everyauth)
  • vérification par e-mail et processus de mot de passe oublié (envoyer un e-mail avec Jeton, non pris en charge par Passeport)
  • modularité: utilisez uniquement ce dont vous avez besoin
  • flexibilité: personnaliser toutes les choses

Jetez un oeil aux exemples .

3
répondu zemirco 2014-02-03 08:53:06

Une interprétation différente de l'authentification est Passwordless, un module d'authentification par jeton pour express qui contourne le problème inhérent aux mots de passe [1]. Il est rapide à mettre en œuvre, ne nécessite pas trop de formulaires et offre une meilleure sécurité pour l'utilisateur moyen (divulgation complète: je suis l'auteur).

[1]: les mots de passe sont Obsolètes

3
répondu florian 2014-06-29 11:42:55

Il existe un projet appelé Drywallqui implémente un système de connexion utilisateur avec Passport et dispose également d'un panneau d'administration de gestion des utilisateurs. Si vous recherchez un système d'authentification et de gestion utilisateur complet similaire à ce que Django a sauf pour Node.js, c'est ça. J'ai trouvé que c'était un très bon point de départ pour construire une application de nœud qui nécessitait un système d'authentification et de gestion des utilisateurs. Voir la réponse de Jared Hanson pour plus d'informations sur la façon dont Passeport fonctionne.

2
répondu lk145 2017-05-23 10:31:22

Voici deux bibliothèques GitHub populaires pour l'authentification node JS:

Https://github.com/jaredhanson/passport ( influençable )

Https://nodejsmodules.org/pkg/everyauth

2
répondu Soman Dubey 2014-03-21 17:02:04

Exemple simple et rapide en utilisant mongo, pour une API qui fournit l'authentification de l'utilisateur pour ie Angular client

Dans l'application.js

var express = require('express');
var MongoStore = require('connect-mongo')(express);

// ...

app.use(express.cookieParser());
// obviously change db settings to suit
app.use(express.session({
    secret: 'blah1234',
    store: new MongoStore({
        db: 'dbname',
        host: 'localhost',
        port: 27017
    })
}));

app.use(app.router);

Pour votre itinéraire quelque chose comme ceci:

// (mongo connection stuff)

exports.login = function(req, res) {

    var email = req.body.email;
    // use bcrypt in production for password hashing
    var password = req.body.password;

    db.collection('users', function(err, collection) {
        collection.findOne({'email': email, 'password': password}, function(err, user) {
            if (err) {
                res.send(500);
            } else {
                if(user !== null) {
                    req.session.user = user;
                    res.send(200);
                } else {
                    res.send(401);
                }
            }
        });
    });
};

Ensuite, dans vos routes qui nécessitent l'authentification, vous pouvez simplement vérifier la session utilisateur:

if (!req.session.user) {
    res.send(403);
}
1
répondu Mister P 2014-03-11 09:43:39

Voici une nouvelle bibliothèque d'authentification qui utilise des jetons horodatés. Les jetons peuvent être envoyés par courriel ou envoyés par SMS aux utilisateurs sans avoir besoin de les stocker dans une base de données. Il peut être utilisé pour l'authentification sans mot de passe ou pour l'authentification à deux facteurs.

Https://github.com/vote539/easy-no-password

Divulgation: je suis le développeur de cette bibliothèque.

0
répondu sffc 2016-08-22 06:59:02