2009-10-31 51 views

回答

3

恕我直言,这是目前不是Acegi的插件的一部分。我向LoginController添加了一个忘记的密码操作:

def forgotPassword = { 
    if (params.username) { 
     User user = User.findByUsername(params.username) 
     if (user) { 
      def password = randomService.generateRandomString(8) 
      user.passwd = authenticateService.encodePassword(password) 
      if (!user.save(flush:true)) { 
       user.errors.each { 
        log.error "err $it" 
       } 
       flash.message = message(code: "LoginController.msg.forgot.error") 
      } else { 
       sendMail { 
        to user.username 
        subject message(code:"LoginController.mail.forgot.subject") 
        body(view:"forgotPasswordEmail", model: [person:user, password:password]) 
       } 
       flash.message = message(code:"LoginController.msg.forgot", args:[user.username]) 
      } 
     } else { 
      flash.message = message(code:"LoginController.msg.forgot.unknown", args:[params.username]) 
     } 
    } 
} 

上面的代码使用Grails邮件插件。

+2

这是一个很好的开始实施。一个潜在的问题是它会自动重置密码,即使其他人请求密码也是如此,所以恶意用户有可能不断地点击“重置密码”并更改用户的密码,但实际上并不希望密码被更改(尽管它们“ d仍然收到电子邮件)。 我们做了这样的事情,但是有一张桌子只有一段时间使用令牌,短时间通过电子邮件发送来重置密码。如果令牌未使用,则密码不变。表中每个用户最多只能有一个令牌。 – 2009-10-31 17:40:59

+0

完全同意。另一种选择是人类网站的一种安全问题,例如“你母亲的娘家姓什么?”。只有正确回答问题,密码才会重置。也许这是有道理的,以取决于acegi插件的独立插件中的账户处理函数“恢复密码”,“恢复登录名”,“删除账户”。 – 2009-11-01 17:08:20

3

谷歌正在失败,因为没有一个。真正无法扭转哈希密码(没有暴力破解和彩虹表),如果是,那就意味着你的系统不安全。

常见模式是用一次性使用令牌通过电子邮件发送忘记密码的用户,然后用它们将密码重置为任何他们想要的。这不是内置到框架中的,但手动操作并不难(我建议使用grails邮件插件)。

3

Acegi插件不支持开箱即用,但如果添加email-confirmation插件,则很容易推出自己的插件。

步骤如下:

创建要求用户输入他们的电子邮件地址和新密码密码重置形式。

处理密码重置表单的控制器操作应该验证数据,并且 使用电子邮件确认插件向用户发送电子邮件并提供链接供他们单击以确认其密码更改。您可以通过在插件添加的EmailConfirmationService服务上调用以下方法来完成此操作。

def sendConfirmation(String emailAddress, String theSubject, Map model = null, 
String userToken = null) 

其中:

emailAddress = address of user changing password 
theSubject = subject of e-mail sent 
model = any data passed to GSP that creates e-mail body 
userToken = hashed user's password 

当用户点击电子邮件中的链接(请参阅有关如何自定义此电子邮件信息的插件文档),该onConfirmation关闭该服务将被调用。

此截止时间应在Bootstrap.groovy分配是这样的:

def emailConfirmationService 

def init = { servletContext -> 

    emailConfirmationService.onConfirmation = { email, hashedPassword -> 

    User user = User.findByEmail(email) 
    user.passwd = hashedPassword 
    if (!user.save()) { 
     // Handle this error, somehow.... 
    } 

    // Then return a map which will redirect the user to the login screen (for example) 
    [controller:'userProfile', action:'login'] 
    } 
} 

注意用户的电子邮件和哈希密码被传递到这个闭合,使您能够重置并保存用户的密码。