回答:
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などを介した認証に追加の戦略を利用できます。必要に応じて、カスタム戦略をプラグインできます。
done(null,false,{ message:'Incorrect username.' })
。これらのパラメーターが何であるかがわからないので、ひどいです。
あなたが多くの良いライブラリーを見つけられなかった理由は、認証にライブラリーを使用することはほとんど過剰に設計されているためだと思います。
あなたが探しているのは、単にセッションバインダーです:)以下とのセッション:
if login and user == xxx and pwd == xxx
then store an authenticated=true into the session
if logout destroy session
それでおしまい。
私も接続を使用していますが、2つの理由で接続認証を使用していません。
IMHOは、connect-authを破壊します。非常に強力で読みやすい、connectのオニオンリングアーキテクチャです。ノーゴー-私の意見:)。コネクトの仕組みとオニオンリングのアイデアについては、こちらの非常に優れた短い記事をご覧ください。
あなたが書いたように-データベースまたはファイルで基本的なまたはhttpログインを使用したい場合。接続認証は大きすぎます。OAuth 1.0、OAuth 2.0、Coなどに適しています
(完了です。テストのために実行するだけですが、本番環境で使用する場合は、必ずhttpsを使用してください)(そしてREST-Principle-Compliantになるには、GET-Request b / cの代わりにPOST-Requestを使用する必要がありますあなたは状態を変更します:)
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の変更がある可能性があります。何かを変更する必要がある場合は、コメントを追加してください。
接続ミドルウェアへの接続認証プラグインがまさに私が必要とするものであるように見えます:http : //wiki.github.com/ciaranj/connect-auth/creating-a-form-based-strategy
私はエクスプレス[ http://expressjs.com ] を使用しているため、エクスプレスはコネクトからサブクラス化(ok-プロトタイプ)されているので、コネクトプラグインは非常にうまく適合します。
基本的に同じものを探していました。具体的には、次のものが必要でした。
私がやったことは、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("/");
}
});
});
とにかく、このアプローチは主に柔軟でシンプルになるように設計されています。私はそれを改善するための多くの方法があると確信しています。あれば、フィードバックをよろしくお願いします。
編集:これは簡単な例です。運用システムでは、パスワードをプレーンテキストで保存および比較することは決してありません。コメント投稿者が指摘するように、パスワードのセキュリティ管理に役立つライブラリがあります。
これは、私のプロジェクトの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;
}
};
認証の別の方法はPasswordless です。これは、パスワードの固有の問題を回避する、エクスプレス用のトークンベースの認証モジュールです[1]。実装は高速であり、あまり多くのフォームを必要とせず、平均的なユーザーに優れたセキュリティを提供します(完全な開示:私は作成者です)。
[1]:パスワードは廃止されました
数年が経ちましたが、Expressの認証ソリューションを紹介します。それはLockitと呼ばれます。プロジェクトはGitHubにあり、短い紹介は私のブログにあります。
では、既存のソリューションとの違いは何ですか?
require('lockit')
、lockit(app)
、行われusername
とpassword
。例を見てください。
Passportを使用したユーザーログインシステムを実装し、ユーザー管理の管理パネルを備えた、Drywallというプロジェクトがあります。Djangoが持っているもののようなNode.jsに似た、完全な機能を備えたユーザー認証および管理システムを探しているなら、これがまさにそれです。ユーザー認証と管理システムを必要とするノードアプリを構築するための非常に良い出発点であることがわかりました。Passportのしくみについては、Jared Hansonの回答を参照してください。
以下は、ノードjs認証用の2つの一般的なGithubライブラリです。
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);
}
次に、タイムスタンプ付きのトークンを使用する新しい認証ライブラリを示します。トークンは、データベースに保存する必要なく、ユーザーにメールまたはテキストで送信できます。パスワードなしの認証または2要素認証に使用できます。
https://github.com/vote539/easy-no-password
開示:私はこのライブラリの開発者です。
Microsoft WindowsユーザーアカウントでのSSO(シングルサインオン)による認証が必要な場合。https://github.com/jlguenego/node-expose-sspiを試してみてください。
req.sso
すべてのクライアントユーザー情報(ログイン、表示名、sid、グループ)を含むオブジェクトを提供します。
const express = require("express");
const { sso, sspi } = require("node-expose-sspi");
sso.config.debug = false;
const app = express();
app.use(sso.auth());
app.use((req, res, next) => {
res.json({
sso: req.sso
});
});
app.listen(3000, () => console.log("Server started on port 3000"));
免責事項:私はnode-expose-sspiの作者です。
軽量のゼロ構成ユーザー認証モジュール。それは別のデータベースを必要としません。
https://www.npmjs.com/package/sweet-auth
それは次のように簡単です:
app.get('/private-page', (req, res) => {
if (req.user.isAuthorized) {
// user is logged in! send the requested page
// you can access req.user.email
}
else {
// user not logged in. redirect to login page
}
})
omniauth
(rails)またはpythonに相当するものsocial-auth
。PHP(およびその他の一般的なWebサーバー言語)ユーザーも、同等のものを自由に追加できます。