gpt4 book ai didi

grails - Bcrypt 为相同的输入生成不同的哈希?

转载 作者:行者123 更新时间:2023-12-03 07:49:19 26 4
gpt4 key购买 nike

我刚刚在我的新 grails 项目中添加了注册功能。为了测试它,我通过提供电子邮件和密码进行了注册。在将密码保存到数据库之前,我正在使用 bcrypt 算法对密码进行哈希处理。

但是,当我尝试使用注册时提供的相同电子邮件和密码登录时,登录失败。我调试了应用程序,发现当我尝试与数据库中已经散列的散列进行比较时,为相同密码生成的散列不同,因此登录失败( Registration.findByEmailAndPassword(params.email,hashPassd ) 在 LoginController.groovy 中返回 null )。

这是我的域类 Registration.groovy:

class Registration {

transient springSecurityService

String fullName
String password
String email

static constraints = {
fullName(blank:false)
password(blank:false, password:true)
email(blank:false, email:true, unique:true)
}

def beforeInsert = {
encodePassword()
}

protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}

这是我的 LoginController.groovy:
class LoginController {

/**
* Dependency injection for the springSecurityService.
*/
def springSecurityService

def index = {
if (springSecurityService.isLoggedIn()) {
render(view: "../homepage")
}
else {
render(view: "../index")
}
}

/**
* Show the login page.
*/
def handleLogin = {

if (springSecurityService.isLoggedIn()) {
render(view: "../homepage")
return
}

def hashPassd = springSecurityService.encodePassword(params.password)
// Find the username
def user = Registration.findByEmailAndPassword(params.email,hashPassd)
if (!user) {
flash.message = "User not found for email: ${params.email}"
render(view: "../index")
return
} else {
session.user = user
render(view: "../homepage")
}
}
}

这是我的 Config.groovy 中的一个片段,告诉 grails 使用 bcrypt 算法来散列密码和 key 的轮数:
grails.plugins.springsecurity.password.algorithm = 'bcrypt'
grails.plugins.springsecurity.password.bcrypt.logrounds = 16

最佳答案

Jan 是正确的 - bcrypt 按设计不会为每个输入字符串生成相同的哈希值。但是有一种方法可以检查散列密码是否有效,并将其合并到相关的密码编码器中。因此,为 passwordEncoder 添加依赖注入(inject) Controller 中的 bean ( def passwordEncoder ) 并将查找更改为

def handleLogin = {

if (springSecurityService.isLoggedIn()) {
render(view: "../homepage")
return
}

def user = Registration.findByEmail(params.email)
if (user && !passwordEncoder.isPasswordValid(user.password, params.password, null)) {
user = null
}

if (!user) {
flash.message = "User not found for email: ${params.email}"
render(view: "../index")
return
}

session.user = user
render(view: "../homepage")
}

请注意,您不对 isPasswordValid 的密码进行编码。 call - 传递明文提交的密码。

此外 - 完全不相关 - 将用户存储在 session 中是一个坏主意。 auth 主体很容易获得并存储用户 ID,以便根据需要轻松重新加载用户(例如 User.get(springSecurityService.principal.id) 。当您是服务器的唯一用户时,存储断开连接的潜在大型 Hibernate 对象在开发模式下效果很好,但是可能会严重浪费内存并迫使您解决断开连接的对象(例如,必须使用 merge 等)。

关于grails - Bcrypt 为相同的输入生成不同的哈希?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8467819/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com