MeteorJS 防止某些用户登录的正确方法

MeteorJS correct way to prevent some users from logging in

在 MeteorJS 应用程序中,我需要阻止某些用户登录。

特别是,如果用户一直在使用非常旧的密码,例如超过 90 天,我们想强制他们在重新登录之前重设密码。

作为试图实现此目的的 MeteorJS 初学者,我在管理员登录 javascript 文件中有以下代码,位于 views 文件夹中的某处:

Template.adminLogin.events({
    'submit #frm-admin-login': function(e) {
        e.preventDefault();

        if ($('#frm-admin-login').validate().form()) {
            var loginProperties = {
                email: $(e.target).find('input[name=email]').val(),
                password: $(e.target).find('input[name=password]').val()
            };

            Meteor.loginWithPassword(loginProperties.email, loginProperties.password, function(err) {
                if (err) return throwError(err);
                
                if (Meteor.userId()) {
                
                    let seconds = new Date().getTime() - Meteor.user().lastPasswordResetAt.getTime();
                    let days = seconds / (1000*60*60*24);
                    let daysToForceResetPassword = parseInt(Meteor.DAYS_TO_FORCE_RESET_PASSWORD);
                    
                    $(e.target).find('input[name=password]').val('');

                    if (days > daysToForceResetPassword){

                        // log out user, and 
                        // show error that you must reset password in order to login

                    }else{

                        // no problem, proceed to dashboard
                        MNotifications.clear({type: 'error'});
                        Router.go('adminDashboard');    
                    }
                }
            });
        }
    }
});

这个可以,但是感觉很奇怪,我先让用户登录,然后在我们意识到他需要立即重设密码时,我们立即把他从视图层注销。

这样做是否正确,或者是否有更好的方法在内部自定义或修改 Meteor.loginWithPassword() 方法,使其甚至根本不允许登录?

您应该使用 validateLoginAttempt docs

在服务器上执行此检查

通过抛出 Meteor.Error,您可以向客户端报告特定的错误消息并提醒用户从那里重置密码:

示例实现:

// on server
Accounts.validateLoginAttempt(function (attempt) {
  if (!attempt.allowed) return false;
  
  if (attempt.user) {
    let seconds = attempt.user.lastPasswordResetAt.getTime();
    let days = seconds / (1000 * 60 * 60 * 24);
    let daysToForceResetPassword = parseInt(Meteor.settings.DAYS_TO_FORCE_RESET_PASSWORD);

    if (days > daysToForceResetPassword) {
      throw new Meteor.Error('expired-password')
    }
  }
  return true;
});

// on client
Meteor.loginWithPassword(loginProperties.email, loginProperties.password, function(err) {
  if (err.error === 'expired-password') {
    // show error that you must reset password in order to login
  }
  if (err) return throwError(err);

  // else no problem, proceed to dashboard
  MNotifications.clear({type: 'error'});
  Router.go('adminDashboard');    
});