web-dev-qa-db-ja.com

node.jsのユーザー認証ライブラリ?

Node.js用の既存のユーザー認証ライブラリはありますか?特に、ユーザーのパスワード認証を実行して(カスタムバックエンド認証DBを使用)、そのユーザーをセッションに関連付けることができるものを探しています。

Authライブラリを作成する前に、人々が既存のライブラリを知っているかどうかを確認しました。グーグル検索で明らかなものを見つけることができませんでした。

-シュレヤス

271
shreddd

接続ミドルウェアへのconnect-authプラグインはまさに私が必要なもののように見えます: http://wiki.github.com/ciaranj/connect-auth/creating-a-form-b​​ased-strategy

Express [ http://expressjs.com ]を使用しているので、connectプラグインは非常にうまく適合します。これは、expressがconnect

26
shreddd

ConnectまたはExpressの認証フレームワークを探している場合、Passportは調査する価値があります。 https://github.com/jaredhanson/passport

(開示:私はパスポートの開発者です)

Connect-authとeveryauthの両方を調査した後、Passportを開発しました。どちらも素晴らしいモジュールですが、私のニーズには合いませんでした。もっと軽くて目立たないものが欲しかった。

Passportは個別のモジュールに分割されているため、必要なもののみを使用することを選択できます(OAuth、必要な場合のみ)。また、Passportはアプリケーションにルートをマウントしないため、認証をいつどこで行うかを柔軟に決定でき、認証が成功または失敗したときに何が起こるかを制御するフックがあります。

たとえば、フォームベース(ユーザー名とパスワード)認証をセットアップする2段階のプロセスを次に示します。

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('/');
  });

Facebook、Twitterなどを介した認証には、追加の戦略を利用できます。必要に応じて、カスタム戦略をプラグインできます。

229
Jared Hanson

セッション+ If

多くの優れたライブラリを見つけられなかったのは、認証にライブラリを使用することのほとんどが過剰に設計されているためだと思います。

あなたが探しているのは単にセッションバインダーです:)とのセッション:

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

それでおしまい。


Connect-authプラグインが道であるというあなたの結論に同意しません。

connect も使用していますが、次の2つの理由でconnect-authを使用していません。

  1. 私見は、コネクトの非常に強力で読みやすいオニオンリングアーキテクチャであるコネクト認証を破ります。ノーゴー-私の意見:)。 connectの仕組みとオニオンリングのアイデアに関する非常に優れた短い記事を見つけることができます here

  2. 書かれているように、データベースまたはファイルで基本ログインまたはhttpログインを使用する場合。 Connect-authが大きすぎます。 OAuth 1.0、OAuth 2.0&Coのようなものに向いています


接続を使用した非常に簡単な認証

(完了です。テストのために実行するだけですが、実稼働環境で使用する場合は、必ずhttpsを使用してください)状態を変更する:)

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);

注意

私は1年以上前にこの声明を書きましたが、現在アクティブなノードプロジェクトはありません。そのため、ExpressにはAPIが変更される可能性があります。何か変更する必要がある場合は、コメントを追加してください。

88
Matthias

私は基本的に同じものを探していました。具体的には、次のものが必要でした。

  1. コネクトのミドルウェア機能をラップするexpress.jsを使用するには
  2. 「フォームベース」認証
  3. ルートが認証されるきめ細かな制御
  4. ユーザー/パスワード用のデータベースバックエンド
  5. セッションを使用する

私がやったことは、認証したい各ルートに引数として渡すミドルウェア関数check_authを作成することでした。 check_authは単にセッションをチェックし、ユーザーがログインしていない場合は、次のようにログインページにリダイレクトします。

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();
}

次に、各ルートについて、この関数がミドルウェアとして渡されるようにします。例えば:

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

最後に、ログインプロセスを実際に処理する必要があります。これは簡単です。

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

とにかく、このアプローチは主に柔軟でシンプルになるように設計されました。私はそれを改善する多くの方法があると確信しています。もしあれば、あなたのフィードバックがとても欲しいです。

編集:これは簡単な例です。実稼働システムでは、パスワードをプレーンテキストで保存および比較する必要はありません。コメント者が指摘しているように、パスワードセキュリティの管理に役立つライブラリがあります。

14
Tom

サードパーティ/ソーシャルネットワークログインの統合が必要な場合は、 everyauth もご覧ください。

13
Peter Lyons

これが私のプロジェクトの1つからの基本認証のコードです。 CouchDBと追加の認証データキャッシュに対して使用しますが、そのコードを削除しました。

リクエスト処理を認証方法でラップし、認証が失敗した場合の2番目のコールバックを提供します。成功コールバックは、追加のパラメーターとしてユーザー名を取得します。失敗コールバックで、間違った資格情報または欠落している資格情報を持つ要求を正しく処理することを忘れないでください。

/**
 * 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
b_erb

別の認証方法は、パスワードの固有の問題を回避するエクスプレス用の トークンベースの認証 モジュールであるPasswordlessです[1]。実装は高速で、多くのフォームを必要とせず、平均的なユーザーにより優れたセキュリティを提供します(完全な開示:私は著者です)。

[1]: パスワードは廃止されました

4
florian

数年が経ち、Expressの認証ソリューションを紹介したいと思います。 Lockitと呼ばれます。プロジェクトは GitHub にあり、短いイントロは my blog にあります。

では、既存のソリューションとの違いは何ですか?

  • 使いやすい:DBのセットアップ、npmインストール、require('lockit')lockit(app)、完了
  • すでに組み込まれているルート(/ signup、/ login、/ forgot-passwordなど)
  • すでに組み込まれているビュー(Bootstrapに基づくが、独自のビューを簡単に使用できます)
  • angularJS/Ember.jsシングルページアプリのJSON通信をサポートします
  • OAuthおよびOpenIDはサポートしていません。 usernameおよびpasswordのみ。
  • すぐに使えるいくつかのデータベース(CouchDB、MongoDB、SQL)で動作します
  • テストがあります(Drywallのテストが見つかりませんでした)
  • アクティブに維持されます(everyauthと比較して)
  • 電子メールの確認とパスワードを忘れた場合のプロセス(トークン付きの電子メールの送信、Passportではサポートされていません)
  • モジュール性:必要なものだけを使用する
  • 柔軟性:すべてをカスタマイズ

examples を見てください。

3
zemirco

以下に、ノードjs認証用の2つの一般的なGithubライブラリを示します。

https://github.com/jaredhanson/passport (提案可能)

https://nodejsmodules.org/pkg/everyauth

2
Soman Dubey

Drywall と呼ばれるプロジェクトがあり、これは Passport でユーザーログインシステムを実装し、ユーザー管理管理パネルもあります。 Djangoのようなものに似た、Node.js向けの完全な機能を備えたユーザー認証および管理システムを探しているなら、これがそれです。ユーザー認証および管理システムを必要とするノードアプリを構築するための非常に良い出発点であることがわかりました。 Passportの仕組みについては、 Jared Hansonの回答 を参照してください。

2
lk145

Angularクライアントのユーザー認証を提供するAPIのmongoを使用した簡単な簡単な例

app.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);

次のようなルートの場合:

// (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);
                }
            }
        });
    });
};

次に、認証が必要なルートで、ユーザーセッションを確認するだけです。

if (!req.session.user) {
    res.send(403);
}
1
Mister P

これは、タイムスタンプ付きトークンを使用する新しい認証ライブラリです。トークンは、データベースに保存することなく、ユーザーにメールまたはテキストで送信できます。パスワードレス認証または2要素認証に使用できます。

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

開示:私はこのライブラリの開発者です。

0
sffc