0

我有一个包含 3 个字段的组域对象 - 用户名、密码和电子邮件地址 在保存对象之前,我对电子邮件地址进行了混淆,因此它不会作为业务需求以明文形式存储在我们的数据库中

当我在域对象上调用 validate 时,我注意到了一些奇怪的行为。字段的约束如下

    userName (nullable: false, unique: false,blank: false, size: 4..200,widget: "textField", matches: "[a-zA-Z0-9, .-@#~{}!£%&*^()-_]+")
    password (nullable: false, unique: false,blank: false, size: 4..200,widget: "textField", password: true, matches: "[a-zA-Z0-9, .-@#~{}!£%&*^()-_]+")
    emailAddress (nullable: false, unique: false,blank: false, size: 5..200,widget: "textField",email: true, matches: "[a-zA-Z0-9, .-@#~{}!£%&*^()-_]+")

对于该对象,我验证它以确保所有值都符合预期(emailAddress 尚未混淆)如果有效,我会混淆电子邮件地址,然后使用 validate: false 值调用 save

奇怪的行为如下如果我填写了有效的电子邮件地址和有效的密码 - 对象在 userName 字段上的验证失败,因为它不能为空

如果我填写了有效的电子邮件地址和有效的用户名 - 对象在密码字段上的验证失败,因为它不能为空,而且在电子邮件地址上也不能为空,它会在消息中显示电子邮件地址的混淆值

我首先认为是混淆导致了问题,但在输入密码字段的情况下它工作正常。两种情况下的代码流完全相同。

在我混淆电子邮件地址后未填写密码字段的情况下,grails 是否有可能调用 validate 方法?

代码流程如下

        def userLoginUserInstance = UserLoginUser.get(params.id)
        userLoginUserInstance.properties = params

        if (userLoginUserInstance.validate()) {
            //perform updates to database by obfuscating email address first - working fine
        } else {
                def newObfuscatedEmailAddress =  userLoginUserInstance.emailAddress.encodeAsBase64();

                userLoginUserInstance.setEmailAddress(newObfuscatedEmailAddress);

                render(view: "edit", model: [userLoginUserInstance: userLoginUserInstance])
        }

验证失败时电子邮件地址被混淆的原因是 gsp 读取了一个临时变量,该变量具有一个 getter,而不是对电子邮件地址进行去混淆处理。当上面的代码在未设置用户名的情况下运行时,它可以正常工作并且电子邮件地址显示为正常。如果密码为空,则会显示密码错误,但混淆的电子邮件地址也会显示为无效。

在进一步分析中,当我运行以下代码行时发生了验证问题

 userLoginUserInstance.setEmailAddress(newObfuscatedEmailAddress);

我理解为什么会在从数据库中检索 userLoginUserInstance 时发生这种情况。让我感到困惑的是,这并非在所有情况下都会发生

4

2 回答 2

1

发生验证错误是因为您试图将Base64字符串存储到具有电子邮件约束的属性中:

"foo@bar.com".encodeAsBase64()

结果是

Zm9vQGJhci5jb20=

因此,现在当您的User实体再次刷新到数据库时,当然会发生另一个验证,抱怨这不是有效的电子邮件地址。

之所以没有在所有场景中引发验证错误,原因可能是您没有强制执行 auser.save()user.save(flush:true)

这意味着电子邮件地址不会临时更新,而是稍后更新。为了更好地了解发生了什么,在分配电子邮件后添加另一个验证块。

于 2013-02-12T19:34:58.737 回答
0

很抱歉没有早点回来

我通过将一个新对象而不是数据库中的对象传递回视图来解决这个问题 因为我需要混淆电子邮件地址,所以这个用例确实过于复杂

感谢您对这个人的帮助

问候达米安

于 2013-03-01T20:14:52.383 回答