web-dev-qa-db-ja.com

node.jsでログイン認証を実装する方法

私はこのノードサーバーを実行しています:

var server=http.createServer(function(request, responsehttp) {
    if (request.method == 'POST') {
        var body = '';
        request.on('data', function (data) {
            body += data;
        });
        request.on('end', function () {
            var POST = qs.parse(body);
            processquery(POST, request, responsehttp);
        });
    } else {
        var url_parts = url.parse(request.url, true);
        var query = url_parts.query;
        console.log(query);
        processquery(query, request, responsehttp);
    }
});

このサーバーのログインフォームを追加したいので、ユーザーが認証されると表示されます。

   function processquery(query, request, responsehttp){
    var returnResult = function (data){
        responsehttp.end(JSON.stringify(data));
    };

    if (!query.command) {
        fileprocess(request, responsehttp);
    }
    responsehttp.writeHead(200, {"Content-Type": "application/json"});
    switch(query.command) {
        case 'logout':
            logout(query, returnResult);
            break;
        case 'login':
            login(query, returnResult);
            break;
    }    
}

コマンドが指定されていない場合、ファイルをクライアントに返すインプロセスクエリ関数なので、ログインコマンドをクライアントからサーバーに送信できますが、ログインコマンドをユーザー名passwordで受け取ったときに何をすべきか、ログイン要求をどのように渡すかログインの成功または失敗を返します。この部分を書くために私は助けが必要です。

私が試したもの。

function login(request, callback) {
    if(request.username==users[request.username] && request.password==users[request.username].password) {
        users[request.username].auth=true;
        var data = {result:'success','message':'login successful'};
        callback(data);
    } else {
        var data = {result:'error','message':'login incorrect'};
        callback(data);
    }
}

ログイン関数でリクエスト変数を追加し、request.sessionが未定義であると言うrequest.session変数を設定してみました。

すべてのユーザーのログイン認証を適切に維持できるこのログインモジュールをどのように作成できるかを提案してください。

73
XMen

Express.js を使用して行う方法は次のとおりです。

1)ユーザーが認証されているかどうかを確認します:ユーザーの認証が必要なすべてのルートで使用するCheckAuthというミドルウェア関数があります:

function checkAuth(req, res, next) {
  if (!req.session.user_id) {
    res.send('You are not authorized to view this page');
  } else {
    next();
  }
}

次のようにルートでこの関数を使用します。

app.get('/my_secret_page', checkAuth, function (req, res) {
  res.send('if you are viewing this page it means you are logged in');
});

2)ログインルート:

app.post('/login', function (req, res) {
  var post = req.body;
  if (post.user === 'john' && post.password === 'johnspassword') {
    req.session.user_id = johns_user_id_here;
    res.redirect('/my_secret_page');
  } else {
    res.send('Bad user/pass');
  }
});

3)ログアウトルート:

app.get('/logout', function (req, res) {
  delete req.session.user_id;
  res.redirect('/login');
});      

Express.jsの詳細については、こちらのサイトをご覧ください。 expressjs.com/en/guide/routing.html より複雑なものが必要な場合は、チェックアウト everyauth (facebook、Twitterなどの多くのauthメソッドが利用可能です;それに関する良いチュートリアル here )。

240
alessioalex

実際、これは実際には質問の答えではありませんが、これはそれを行うためのより良い方法です。

HTTPサーバーとして connect / express を使用することをお勧めします。あなたは明らかに車輪を再発明したくありません。あなたの場合、セッション管理はconnect/expressを使用するとはるかに簡単になります。

それに加えて、認証には everyauth を使用することをお勧めします。多くの認証戦略をサポートしています。迅速な開発に最適です。

これらはすべて、ドキュメントからコピーを貼り付けるだけで簡単にダウンできます!

6

Faridの疑似回答に追加するには、

Passport.js over everyauth の使用を検討してください。

この質問 への回答は、違いについての洞察を提供します。


ユーザー認証をGoogle、Facebook、または別のWebサイトにオフロードすることには多くの利点があります。アプリケーションの要件が、Passportを唯一の認証プロバイダーとして使用したり、従来のログインと一緒に使用したりできる場合は、ユーザーのエクスペリエンスをより簡単にすることができます。

3
Luke M Willis

@alessioalexの回答は、新規ノードユーザー向けの完璧なデモです。しかし、とにかく、login以外のすべてのルートにcheckAuthミドルウェアを書き込むことは難しいため、app.useを使用してcheckAuthをすべてのルートから1つのエントリに移動することをお勧めします。例えば:

function checkAuth(req, res, next) {
  // if logined or it's login request, then go next route
  if (isLogin || (req.path === '/login' && req.method === 'POST')) {
    next()
  } else {
    res.send('Not logged in yet.')
  }
}

app.use('/', checkAuth)
2
Chang

私はこの答えを試しましたが、うまくいきませんでした。私はWeb開発の初心者でもあり、mlabを使用したクラスを受講しましたが、解析が好きなので、最適なソリューションを探す必要がありました。 expressJSで解析を使用する現在のソリューションは次のとおりです。

1)ユーザーが認証されているかどうかを確認します:isLogginInという名前のミドルウェア関数があり、ユーザーを認証する必要があるすべてのルートで使用します。

 function isLoggedIn(req, res, next) {
 var currentUser = Parse.User.current();
 if (currentUser) {
     next()
 } else {
     res.send("you are not authorised");
 }
}

次のようにルートでこの関数を使用します。

  app.get('/my_secret_page', isLoggedIn, function (req, res) 
  {
    res.send('if you are viewing this page it means you are logged in');
  });

2)ログインルート:

  // handling login logic
  app.post('/login', function(req, res) {
  Parse.User.enableUnsafeCurrentUser();
  Parse.User.logIn(req.body.username, req.body.password).then(function(user) {
    res.redirect('/books');
  }, function(error) {
    res.render('login', { flash: error.message });
  });
});

3)ログアウトルート:

 // logic route
  app.get("/logout", function(req, res){
   Parse.User.logOut().then(() => {
    var currentUser = Parse.User.current();  // this will now be null
    });
        res.redirect('/login');
   });

これは私にとって非常にうまく機能し、ここでドキュメントを完全に参照しました https://docs.parseplatform.org/js/guide/#users

@alessioalexの回答に感謝します。私は最新のプラクティスでのみ更新しました。

1
felix