2016-04-15 17 views
6

Vì lý do bảo mật, chúng tôi tạo người dùng và gửi cho họ mật khẩu được tạo tạm thời. Tại lần đăng nhập đầu tiên của họ, người dùng nên thay đổi mật khẩu của nó trước khi tiếp tục điều hướng các trang được bảo vệ.Mật khẩu tạm thời của hộ chiếu (thay đổi khi đăng nhập lần đầu)

Tôi đang sử dụng trang web express/node đang chạy mô-đun hộ chiếu tại địa phương. Đăng ký, đăng nhập vào tất cả người dùng. Nhưng tôi bị mất phương pháp hay nhất để người dùng thay đổi mật khẩu của họ trong lần đăng nhập đầu tiên.

Ý tưởng của tôi là phải làm như sau:

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

Như bạn thấy tôi có một boolean đơn giản (tinyint 0-1) đặt trong cơ sở dữ liệu của tôi (mặc định là 1). Sau đó, tôi sẽ đặt một phương thức đăng sau khi thay đổi thành công, boolean sẽ được đặt thành 0.

Đây có phải là cách chính xác không ('a' not 'the': p)? Làm thế nào về an ninh?

Trả lời

4

Chắc chắn là a cách chính xác. Tôi muốn nói nó hoàn toàn phù hợp với nhu cầu của bạn. Cá nhân tôi thích cách sử dụng trường cơ sở dữ liệu của bạn trực tiếp phản ánh logic nghiệp vụ đằng sau nó.

Alternatives, mặc dù tôi là fan hâm mộ của giải pháp của bạn, có thể là:

Thêm một lĩnh vực lastLogin ngày để cơ sở dữ liệu của bạn mà mặc định là NULL. Điều này sẽ lưu trữ một tem datetime bất cứ khi nào người dùng đăng nhập. Bạn có thể sử dụng nó như một kiểm tra ngầm định nếu người dùng đã từng đăng nhập trước đó. Cá nhân tôi thích có các cột rõ ràng cho mục đích của chúng (như bạn đang làm với cột firstLogin) vì mục đích của cột và logic nghiệp vụ của ứng dụng là rất rõ ràng từ nó.

Một lựa chọn khác sẽ được lưu trữ khi người dùng có cập nhật lần cuối mật khẩu của mình ví dụ: lastPasswordChange mặc định cho NULL cho người dùng mới. Cùng lý luận như trên. Có thể hữu ích nếu bạn muốn người dùng thay đổi mật khẩu của mình sau mỗi n ngày.

Nói bảo mật tôi muốn nói điều này sẽ vững chắc. Miễn là trường firstLogin của bạn mặc định là 1 thì sẽ không có cách nào người dùng mới có thể bỏ qua thay đổi mật khẩu khi đăng nhập lần đầu.

Tuy nhiên, khi người dùng cập nhật mật khẩu của mình, hãy đảm bảo cập nhật trường firstLogin trong cùng một truy vấn hoặc thực hiện cả hai truy vấn bên trong một giao dịch. Bằng cách này, bạn sẽ luôn luôn chắc chắn cả hai mật khẩu trường firstLogin được thay đổi.Nếu vì một lý do nào đó, truy vấn sẽ không thành công nếu bạn có người dùng đã thay đổi mật khẩu của họ và được yêu cầu/buộc phải thay đổi lại mật khẩu hoặc người dùng có mật khẩu được tạo ngẫu nhiên mà không bị yêu cầu thay đổi mật khẩu đó. Làm điều đó trong cùng một truy vấn sẽ đảm bảo cả hai hoặc không được cập nhật cùng một lúc. Làm việc đó bên trong một giao dịch khiến bạn có tùy chọn thất bại/khôi phục giao dịch khi truy vấn bị lỗi.

Ngày lưu ý khác, mã của bạn có thể được viết như thế này (cả theo cách của bạn và điều này là chính xác, nó chỉ là một vấn đề sở thích và thị giác):

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

Nếu bạn muốn một câu trả lời cụ thể hơn cho một trong hai câu hỏi, tôi cần một câu hỏi cụ thể hơn.

+1

Xin lỗi vì đã chấp nhận trễ. Cảm ơn bạn đã trả lời, đã giúp tôi rất nhiều. – Goowik

1

Có thể là một điều tốt để di chuyển logic "kiểm tra lần đầu tiên đăng nhập" vào một phần mềm trung gian riêng biệt thực hiện cho tất cả "tuyến đường đã đăng nhập".

Với đề xuất của bạn ở trên, người dùng có thể chỉ cần điều hướng khỏi/thay đổi mật khẩu sau khi chuyển hướng?

+0

Tôi không nhớ người dùng điều hướng khỏi trang nhưng ngay sau khi anh ấy muốn đăng nhập lại: anh ấy sẽ được yêu cầu lại để thay đổi mật khẩu của anh ấy. Tôi có lẽ sẽ đăng nhập toàn bộ tình huống để kiểm tra điều này. – Goowik

Các vấn đề liên quan