2016-04-15 20 views
6

セキュリティ上の理由から、ユーザーを作成し、一時的に生成されたパスワードを送信します。最初のログイン時に、保護されたページの移動を続行する前に、パスワードを変更する必要があります。Passportローカルの一時パスワード

パスポートローカルモジュールを実行しているエクスプレス/ノードのWebサイトを使用しています。登録、ユーザーログインはすべて動作します。しかし、最初のログイン時にユーザーがパスワードを変更するためのベストプラクティスを見失ってしまいます。

私の考えは、次の操作を実行することでした。

/* POST login page. */ 
router.post('/login', function(req, res, next) { 
    passport.authenticate('local', { successRedirect: '/dashboard/users', 
    failureRedirect: 'pages/login'}, function(err, user, info) { 
    if(err) { 
     console.log('') 
     return res.render('pages/login', {title: 'Login', error: err.message}); 
    } 

    if(!user) { 
     return res.render('pages/login', {title: 'Login', error: info.message}); 
    } 
    return req.logIn(user, function(err) { 
     if(err) { 
     return res.render('pages/login', {title: 'Login', error: err.message}); 
     } else if (user.firstLogin) { 
     return res.redirect('/change-password'); // <- First login 
     } else { 
     return res.redirect('/dashboard/users'); 
     } 
    }); 
    })(req, res, next); 
}); 

あなたは私が私のデータベース内の単純なブール(TINYINT 0-1)セット(デフォルトは1)を持って見ることができるように。その後、ポストメソッドを設定し、変更が成功するとブール値は0に設定されます。

これは正しい方法ですか( 'a': '':p)?セキュリティはどうですか?

答えて

4

間違いなくです。私はそれがあなたのニーズに完全に合っていると言いたい。個人的には、データベースフィールドの使用方法が、その背後にあるビジネスロジックを直接反映しているのが好きです。

代替私はあなたのソリューションのファンですけれども、次のようになります。

NULLデフォルトデータベースにlastLogin日付フィールドを追加します。これは、ユーザーがログオンするたびに日時スタンプを格納します。ユーザーがこれまでにログオンしていた場合は、暗黙のチェックとして使用できます。私は個人的には、アプリケーションの列とビジネスロジックの目的が非常に明確であるため、(あなたのfirstLogin列を使っているように)目的に合わせて明示的な列を持つことを個人的に好みます。

ユーザーが自分のパスワードすなわちlastPasswordChangeは、新規ユーザーのためNULLをデフォルト最後に更新したときに別の方法としては、店になります。上記と同じ推論。 n日ごとにパスワードを変更したい場合に便利です。

セキュリティを話す私はこれが固いと言うでしょう。 firstLoginフィールドのデフォルト値が1であれば、最初のログイン時に新しいユーザーがパスワード変更をスキップする方法はありません。

ただし、ユーザーがパスワードを更新する場合は、同じクエリ内のfirstLoginフィールドを更新してください。またはトランザクション内で両方のクエリを実行してください。このようにして、パスワードfirstLoginフィールドが必ず変更されます。何らかの理由でいずれかのクエリが失敗した場合は、すでにパスワードを変更したユーザーと、パスワードを変更するように頼まれているユーザーまたはパスワードをランダムに生成したユーザーに変更を依頼する必要があります。 同じクエリ内で実行すると、両方を同時に実行するか、どちらも同時に更新されません。トランザクション内で実行すると、いずれかのクエリが失敗したときにトランザクションを失敗/ロールバックするオプションが残ります。別のノートで

、あなたのコードは次のように書くことができます(両方のあなたの方法とこれは正しいですが、それは好みと視覚の問題だ):

/* POST login page. */ 
router.post('/login', function(req, res, next) { 
    passport.authenticate('local', { 
     successRedirect: '/dashboard/users', 
     failureRedirect: 'pages/login' 
    }, function(err, user, info) { 
     if(err) { 
      console.log('') 
      return res.render('pages/login', {title: 'Login', error: err.message}); 
     } 

     if(!user) { 
      return res.render('pages/login', {title: 'Login', error: info.message}); 
     } 
     return req.logIn(user, function(err) { 
      if(err) { 
       return res.render('pages/login', {title: 'Login', error: err.message}); 
      } 

      // Using if/else if/else makes no difference since if the first if is executed 
      // in both cases nothing else will execute due to if/else or the return. 
      // In case the above statement resolves to `false` the effect wills till be the same 

      if (user.firstLogin) { 
       return res.redirect('/change-password'); // <- First login 
      } 
      // The else is not necessary due to the return in the line above. 
      return res.redirect('/dashboard/users'); 
     }); 
    })(req, res, next); 
}); 

あなたはより具体的な答えが欲しい場合どちらの質問にも、より具体的な質問が必要です。

+1

遅く受け入れて申し訳ありません。返事をありがとう、私をたくさん助けてくれた。 – Goowik

1

"ログインを確認する"ロジックを、すべての "ログインしたルート"に対して実行する別のミドルウェアに移動することは、おそらく良いことです。

上記の提案を使用すると、リダイレクト後に/ change-passwordから簡単に移動できますか?

+0

ユーザーはページから移動しても構いませんが、再度ログインするとすぐにパスワードを変更するように求められます。私はおそらくこれをチェックするために全体の状況を記録するでしょう。 – Goowik

関連する問題