class User {
String email
...
String password
static constraints {
password(nullable: false, blank: false, minSize: 6)
}
}
И потом делают валидацию по этому полю а перед сохранением перезаписывают его хешом, например:
user.password = params.password.encodeAsSHA256()
Это некрасиво потому что в этом случае описание поля идёт в разрез с его презентацией на уровне БД. Описание модели должно описывать доменный объект с аспектом как его сохранять в БД, и валидациия указывается уровня БД а не биндинга в контроллере.
Об этом нужно помнить. Например при сохранении не уникального значение в unique поле вы получите исключении на уровне БД а не ошибку на уровне валидатора формы.
Кстати этот пример плох ещё тем что пароль не посолили.
Хеш будет иметь всегда фиксированный размер (в 64 символа в случае с SHA256). Даже у пустой строки, ага.
Если не указан максимальный размер текстового поля то его размер на уровне БД будет 255 символов. А использовать будем всегда только 64, т.е. имеем оверхед.
Или например если вы не указали максимальный размер поля, то он не будет валидироватся на уровне формы и вы получите исключение при сохранении в БД - ещё один наглядный пример что валидация форм не всегда коррелирует с презентацией на уровне БД.
Значит нам нужно указать размер поля, например так:
password(nullable: false, blank: false, maxSize: 64)Хочу обратить внимание что ещё один аргумент против указания характеристик пароля в описании поля в которое будет сохранён его хеш, потому что в таком случае пароль будет ограничен в 64 символа.
Ограничивать размер пароля совершенно глупо, чем длиннее пароль тем выше его надёжность. Я например могу использовать целую фразу и вставлять её автоматически например из брелока.
Какая вам разница какой длины мой пароль? Хоть весь текст Войны и Мира, всё равно ведь в вашей БД он займёт 64 символа. Главное чтобы уложилось в разумное ограничение на длину POST запроса.
Кстати также глупо ограничивать или навязывать мне набор символов, например чтобы обязательно были в нём цифры. Пароль из шестнадцати обычных латинских букв надёжней пароля из шести крякозяблов "qwert$123".
Заключение
Я бы вам посоветовал вот такое описание поля пароляpassword(nullable: false, size: 64..64, bindable: false)Где размер строго 64 символа на хеш (зависит от алгоритма хеширования), и ещё отключен биндинг на всякий пожарный.
При этом валидацию пароля делайте сами, вручную при этом я бы вам советовал на самом деле проверять только что он не пустой, ну в крайнем случае минимальный размер.
Надеюсь эта маленькая заметочка наглядно показала вам сразу несколько ловушек в Grails.
По хорошему для пароля нужно создать отдельный пользовательский тип или constraint.
У кого есть свободное время, сделайте пожалуйста плагин, я был бы очень благодарен.