Spring Boot: bean validation, шифрование паролей

แชร์
ฝัง
  • เผยแพร่เมื่อ 5 ม.ค. 2025

ความคิดเห็น • 302

  • @kunnilinux
    @kunnilinux 6 ปีที่แล้ว +69

    Лучший автор на весь ютуб. Быстрый набор кода, подробные объяснения без воды, приятный голос и шустрая система на компе автора. Смотреть, как вы кодите - отдельное удовольствие. Браво!

    • @1absolute8
      @1absolute8 4 ปีที่แล้ว +3

      только куча ошибок

    • @ElChampi0
      @ElChampi0 3 ปีที่แล้ว +2

      Нуу.... мне, конечно, в целом нравится... Но вот не соглашусь с подробными объяснениями (говорит надо так, а почему так не скажу) и эта мегаскорость, порой даже кадр на паузу уловить не получается, а если не делать паузу каждые 10 секунд, то код даже набрать не успеешь, пока один файл откроешь, он там добавит 10 строчек и закроет файл. Идеальная скорость когда набирается маленький кусочек кода и идет подробное объяснение что это, откуда и зачем, пока его слушаешь успеваешь этот код повторить

  • @farallel6796
    @farallel6796 6 ปีที่แล้ว +29

    Прежде всего я бы хотел выразить Вам свою благодарность за столь полезные видео уроки.) У меня есть к Вам просьба, не могли бы Вы сделать небольшой видео урок, о том как добавить сюда поддержку Cookie, что бы на форме логина была кнопка - "Запомнить меня", и при следующем нашем возвращении на сервер, он нас помнил и не требовал делать логин снова. Я думаю это будет не менее полезный и интересный урок.) Ещё раз спасибо за то, что вы делаете!)

    • @onehornstud
      @onehornstud 6 ปีที่แล้ว +3

      Поддерживаю. Тоже интересно)

    • @letsCodeDru
      @letsCodeDru  6 ปีที่แล้ว +4

      Не надо дублировать сообщения, у меня каждое из них и так отображается в 4 местах :)
      По вопросу: Это будет в следующем видео. Тут дело не в Cookie (они и так используются на сервере), тут работа с сессиями на стороне сервера

    • @Евгений-ч9к2ф
      @Евгений-ч9к2ф 5 ปีที่แล้ว

      @@letsCodeDru чтото терминал в идеи у меня вообще так не работае как у вас...

    • @imennopimenov7408
      @imennopimenov7408 5 ปีที่แล้ว

      @@Евгений-ч9к2ф Вроде как она просто дублирует терминал ОС, у автора Linux и терминал соответствующий

  • @andrevero588
    @andrevero588 6 ปีที่แล้ว +5

    Смотрю эту серию видеоуроков и убеждаюсь в ее шедевральности

  • @Ро́бертДжеймсФишер-в5е
    @Ро́бертДжеймсФишер-в5е 4 ปีที่แล้ว +13

    Небольшая неточность в RegistrationController-е в методе addUser в первом if блоке после проверки на совпадении паролей и после добавления атрибута нужно сделать return "registration";Так как при не совпадении паролей user регистрируется в базе

  • @Vladislav4er
    @Vladislav4er 6 ปีที่แล้ว +21

    Неболшая неточность на уровне опечатки)
    В main.ftl в 29 строке забыли добавить еще class="form-control ${(tagError??)?string('is-invalid', '')}". Иначе он молча его скидывает когда поле длиннее 255, ничего не выводя при этом.

  • @MrAivan87
    @MrAivan87 6 ปีที่แล้ว +5

    Забыл. Спасибо автору за канал, группу в вк и все то что он для нас непросвещенных делает

  • @Igor_Litvinyuk
    @Igor_Litvinyuk 6 ปีที่แล้ว +52

    Если в профиле поменять пароль, то потом нельзя зайти в свою учетную запись ибо она не шифруется в базе данных. Нужно изменить user.setPassword(passwordEncoder.encode(password)); в методе обновления профиля

    • @letsCodeDru
      @letsCodeDru  6 ปีที่แล้ว +8

      Да, точно, совсем забыл добавить шифрование :(
      Спасибо за инфо!

    • @Krainiiserver
      @Krainiiserver 5 ปีที่แล้ว

      спасибо, а то уже прилично подгорало

    • @goodman2156
      @goodman2156 2 ปีที่แล้ว

      Я правильно понимаю, что надо вставить эту строку в метод updateProfile класса UserController, при этом заавтовайрить passwordEncoder?
      Или все-таки в классе UserService? Ты бы лучше пояснил

    • @Orakcool
      @Orakcool 2 ปีที่แล้ว

      @@goodman2156 бизнес логику выноси в сервисы.
      Советую почитать про mvc.
      Вообще перед спрингом хорошо бы java core изучить, написать более простые программки, потом annotation, reflection, jdbc, hibernate и собственно тогда логика спринга станет ясной и понятной.
      Так же рекомендую почитать про паттерны проектирования.
      Ну это все если хочешь стать джава программистом))) А вообще много чего тогда придется изучать... Возможно есть смысл убежать в c#, python, js или новомодный golang пока не поздно :)

    • @romanmanzhula9034
      @romanmanzhula9034 ปีที่แล้ว

      @@goodman2156 UserService -> updateProfile(метод изменения пароля и почты) -> if(в проверку на установку нового пароля)

  • @ИлесЗаудинов
    @ИлесЗаудинов 3 ปีที่แล้ว

    Хочется выразить Вам огромную благодарность! С такими видео спринг изучается с удовольствием.

  • @MrREALball
    @MrREALball 4 ปีที่แล้ว +17

    Для тех, у кого происходит зацикливание бинов в WebSecurityConfig и UserService - просто вынесите
    @Bean
    public PasswordEncoder getPasswordEncoder() {
    return new BCryptPasswordEncoder(8);
    }
    В отдельный конфиг файл, например BeenConfig.java

    • @TheMerdontv
      @TheMerdontv 4 ปีที่แล้ว

      зачёт. помогло. благодарочка)

    • @Booruvcheek
      @Booruvcheek 4 ปีที่แล้ว +3

      Спасибо, помогло.
      Эта ошибка, кстати, будет у всех - проект с Гитхаба выдаёт вот такое: pastebin.com/NEEVEraN
      В другом комменте у человека заработало когда он прописал
      @Lazy перед @Autowired
      private PasswordEncoder passwordEncoder; в websecurityconfig
      Ещё вариант который советуют в ответе на один из комментов -
      "нужно в классе WebSecurityConfig сделать бин getPasswordEncoder() статическим. Тогда по правилам java он будет подгружаться раньше, чем конструктор и не будет никаких проблем."
      В общем, чудеса автомагического создания объектов Spring-ом.

    • @goodman2156
      @goodman2156 2 ปีที่แล้ว

      А как понять, что у тебя именно зацикливание бинов?
      Какая ошибка должна высветиться?

    • @MrREALball
      @MrREALball 2 ปีที่แล้ว

      @@goodman2156 Уже не помню, джаву так и не стал изучать, слишком уж уродский язык по современным меркам. Скорей всего что-то с reference должно выдать или просто зависнуть.

    • @alexandersorokin7596
      @alexandersorokin7596 2 ปีที่แล้ว +3

      @@Booruvcheek статический бин -самый простой способ

  • @nonenone4855
    @nonenone4855 5 ปีที่แล้ว +12

    Это пиздец, как полезно и хорошо подано. Спасибо, автор

    • @letsCodeDru
      @letsCodeDru  5 ปีที่แล้ว +4

      Формулировочка огонь))

    • @marineshkaa_._
      @marineshkaa_._ 2 ปีที่แล้ว

      Согл

  • @MrAivan87
    @MrAivan87 6 ปีที่แล้ว +18

    Для MySQL: в файл миграции можно вписать шифрование по MD5,
    А в бине PasswordEncoder возвратить MessageDigestPasswordEncoder(MD5)...

    • @letsCodeDru
      @letsCodeDru  6 ปีที่แล้ว +1

      Спасибо за дельный коммент :)

    • @YuretsUA
      @YuretsUA 5 ปีที่แล้ว +2

      Похоже что MessageDigestPasswordEncoder(MD5) морально устарел, есть ли вариант шифрования чтобы остаться на BCryptPasswordEncoder ? Что нужно вписать для MySql? по идее приложение не должно зависеть от БД

    • @soul8927
      @soul8927 5 ปีที่แล้ว +1

      @@YuretsUA есть ответ?

    • @alexeysharandin7364
      @alexeysharandin7364 5 ปีที่แล้ว +8

      @@YuretsUA Не запаривайтесь. У вас один admin ради примера должен быть. Возьмите какой нить bcrypt-generator.com/ . Сгенерируйте хэш на пароль и воткните его в add admin sql.
      Или еще проще. Сгенерируйте пользователя с паролем как у админа и пропишите его админу и в add_admin.sql на будущее.

    • @oleksandrsydorenko3303
      @oleksandrsydorenko3303 5 ปีที่แล้ว +4

      Сделал по харкору - не стал делать вторую и третью версию файла миграции, просто создал нового юзера, зашел в базу данных MySQL, вручную прописал роль Админа и всё. Проверил - работает )

  • @SamuilOlegovich
    @SamuilOlegovich 3 ปีที่แล้ว +5

    есть еще один момент - программа не стартует. Говорит не может создать бин. Ссылки зациклены. Помогло решить эту проблему создание нового класса CustomConfig пометить его как @Configuration и вынести в него бин getPasswordEncoder() --> @Configuration public class CustomConfig { @Bean public PasswordEncoder getPasswordEncoder() { return new BCryptPasswordEncoder(8); }}

    • @elchupanebrej
      @elchupanebrej 3 ปีที่แล้ว

      Есть возможность показать полный код классов CustomConfig и WebSecurityConfig? Не совсем понимаю что надо указывать в таком случае в методе configure( AuthenticationManagerBuilder auth ) класса WebSecurityConfig.

    • @dimamikhalishchin5172
      @dimamikhalishchin5172 2 ปีที่แล้ว +1

      @@elchupanebrej Отвечу, может кому пригодиться. Выносится только бин. Поле passwordEncoder остается, метод configure не трогаем.

  • @АлексейБет
    @АлексейБет 5 ปีที่แล้ว +1

    Спасибо, за отличные уроки! В 14:40 появилась ссылка на profile у не зарегистрированного пользователя

    • @Nikita-hu9bk
      @Nikita-hu9bk 5 ปีที่แล้ว

      Так фиксится:

  • @ВикторияК-с5ц
    @ВикторияК-с5ц 4 ปีที่แล้ว +1

    Самые качественные видео на эту тему, /и в рунете, и на англ/ Крутой
    подход, спасибо автору. Следовал видео и получилось сделать интересный
    проект, который любопытно "докручивать" самому. Советы автора помогают
    не утонуть в деталях и не потерять мотивацию. Спасибо ребятам в
    комментах - если вы напоролись на ошибку, решения находил здесь же.
    Успехов! Хватит читать комменты, идите кодить)

  • @btbest_test5916
    @btbest_test5916 2 ปีที่แล้ว +3

    Действительно, в миграции V3 для MySQL могут быть неожиданности с шифрованием уже имеющегося пароля у admin. Поэтому можно обойтись малой кровью: открыть bcrypt online, ввести туда пароль, сгенерировать шифрованный пароль и вставить его в миграцию V2 при создании админа.

  • @chelkatrao
    @chelkatrao 4 ปีที่แล้ว +1

    Большое спасибо за то, что вы такая замечательная команда. 😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊

  • @ilyagvozdev5764
    @ilyagvozdev5764 4 ปีที่แล้ว +8

    Автор, спасибо. Нашел нюанс с spring session. Когда пытаемся залогиниться с пустыми полями, появляется ошибка, но поскольку ошибка висит в сессии, она не сбрасывается корректно т.е. при обычном рефреше страницы, ошибка висит. Мое решение, проверять есть ли параметр в реквесте error, если он есть, берем ошибку из сессии спринга
    ${Session.SPRING_SECURITY_LAST_EXCEPTION.message}

  • @mizantropoff
    @mizantropoff ปีที่แล้ว +1

    Еще косяк в коде - он забыл в RegistrationContriller вернуть "registration" после проверки паролей на совпадение. Сообщение по несовпадению пароля высвечивалось и регистрации не происходило при его тесте только потому, что не было валидировано следующее поле "email". Если бы он с таким кодом ввел разные пароли , но остальные поля были бы валидированы , он бы зарегистрировал невалидного пользователя с несовпадающими паролями.

  • @nelsonnetru
    @nelsonnetru 9 หลายเดือนก่อน

    Друзья! Я одного не понял - когда отредактировали MainController и в аргументы для "/add" вместо text и tag вставили @Valid Message message, как SPRING все равно понимает, что в post-запросе данные формы - это Message? По какому принципу парсит поля из формы?

  • @YuretsUA
    @YuretsUA 5 ปีที่แล้ว +2

    Возник вопрос по валидации логина, как можно разделить ошибки логина и пароля в форме ввода? (к примеру "Пользователь с таким именем не существует", либо "Неверный пароль пользователя") Я так понимаю это нужно делать в переопределенном контроллере логина? Ведь все ошибки мы получаем из Spring Security, а там кроме "Bad credentials" никакой больше информации получить невозможно.

  • @volodymyrkhoma9917
    @volodymyrkhoma9917 5 ปีที่แล้ว

    Спасибо за очередной мегапродуктивный урок.

  • @victormog
    @victormog 6 ปีที่แล้ว +5

    Во вьюхе регистрации переменной _${password2Error}_ взяться неоткуда...
    Или она чем-то генерируется с таким именем?

  • @АндрейЧекановкин-з6ж
    @АндрейЧекановкин-з6ж 4 ปีที่แล้ว +1

    при переходе на страницу регистрации, там сразу же появляются инвалидные поля, хотя я еще ничего не вводил в форму, а если нажать на создание, то почему-то только пароль подсвечивается, хотя в модели явно 6 ошибок лежит, не понимаю, что происходит. И еще сообщение об ошибке не указывается почему-то. Использую thymeleaf

  • @ВиталийШишлаков-т1т
    @ВиталийШишлаков-т1т 5 ปีที่แล้ว +7

    По неизвестной причине, в шаблоне страницы у меня не отображаются ошибки, хотя валидатор отрабатывает. Во время дебага видно, что ошибки в модель попадают.

    • @ИльяЗавертайло
      @ИльяЗавертайло 4 ปีที่แล้ว

      решили проблему?)

    • @user-cx5ry5tt6s
      @user-cx5ry5tt6s 4 ปีที่แล้ว +6

      @@ИльяЗавертайло Я решил)) У меня вместо return "main" было : return "redirect:/main" и изза этого не отображалась ошибка на странице)) после того как сделал просто return "main" всё заработало)

    • @ИльяЗавертайло
      @ИльяЗавертайло 4 ปีที่แล้ว

      @@user-cx5ry5tt6s спасибо тебе, добрый человек :D

    • @amaterasu_in_fire
      @amaterasu_in_fire 2 ปีที่แล้ว

      @@user-cx5ry5tt6s Только теперь по F5 создаются дубли сообщений с таким же текстом

    • @user-cx5ry5tt6s
      @user-cx5ry5tt6s 2 ปีที่แล้ว

      @@amaterasu_in_fire ох е, год)))))

  • @thedzungar2581
    @thedzungar2581 5 ปีที่แล้ว +2

    Люди подскажите пожалуйста в чем проблема ERROR 9864 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed

  • @vyacheslavpesterev3861
    @vyacheslavpesterev3861 6 ปีที่แล้ว

    Отличные уроки, спасибо за труд!

  • @goodman2156
    @goodman2156 2 ปีที่แล้ว

    15:53
    Как сделать то же самое (валидация формы логина), но только на thymeleaf?

  • @igorestela5446
    @igorestela5446 5 ปีที่แล้ว +2

    Всем привет .Не удается установить расширение , выпадает ошибка -
    SQL State : 58P01
    Error Code : 0
    Message : ERROR: could not load library "/Users/***/PostgreSQL/pg11/lib/postgresql/pgcrypto.so": dlopen(/Users/****/PostgreSQL/pg11/lib/postgresql/pgcrypto.so, 10): Library not loaded: /opt/pgbin-build/pgbin/shared/osx_64/lib/libcrypto.1.0.0.dylib
    Referenced from: /Users/****/PostgreSQL/pg11/lib/postgresql/pgcrypto.so
    Кто-то сталкивался с похожей проблемой ? Как можно исправить ?

  • @insurg
    @insurg 4 ปีที่แล้ว +3

    Спасибо за видео! Однако остались кое-какие ошибки, некоторые из них возможно уже были описаны в комментариях.
    1. Ошибка, описанная Vitaliy Мaltsev в комментах выше, решается установкой любого непустого пароля в методе
    UserService#activateUser, однако после успешной активации аккаунта, мы перестали видеть сообщение об этом, т.к. удалили строчку ${message!} из login.ftlh. Ее стоит вернуть, а вот как раз в registration.ftlh ее нужно убрать, т.к. message в модель мы больше не кладем.
    2. При регистрации пользователя если мы заполняем поля валидными данными, но при этом пароли будут разными, то пользователь все равно будет создан и перенаправлен на страницу логина. Как вариант, в ControllerUtils можно добавить статик метод, который будет проверять модель на наличие ошибок: model.asMap().keySet().stream().anyMatch(key -> key.contains("Error")); а потом использовать его чтобы в нужном месте вызвать return "registration".

  • @AnnaSmirnova1
    @AnnaSmirnova1 5 ปีที่แล้ว

    Спасибо!!!
    Поправляйтесь скорее!! Ждем стримов))

  • @ilias3624
    @ilias3624 5 ปีที่แล้ว +1

    Не забудьте прописать passwordEncoder в методе updateProfile(), а то будет ошибка при смене пароля - он сменится, но залогиниться потом не получится.

  • @evgeniymurenko4101
    @evgeniymurenko4101 6 ปีที่แล้ว +3

    Спасибо, за отличный видео урок!
    При регистрации пользывателя, если вводишь только разные пароли - то он создает пользывателя и перекидывает на логина.
    Нужно после проверки паролей и имейла, сделать еще проверку модели на null и туда можно вынести общий ретурн.

    • @Vladislav4er
      @Vladislav4er 6 ปีที่แล้ว +4

      Пытался пофиксить багу, в итоге все заработало когда я в проверку паролей между собой добавил return "registration". Без него он добавлял пользователя если были указаны имя, почта, но разные пароли
      if (user.getPassword() != null && !user.getPassword().equals(user.getPassword2())) {
      model.addAttribute("passwordError", "Passwords are different!");
      return "registration";
      }
      И желательно эту проверку поставить после проверки if(bindingResult.hasErrors()), потому что так он будет всегда говорить что они разные, даже если второе поле пустое. Но если поставить после, то тогда он проверит сначала на пустоту и скажет это

    • @letsCodeDru
      @letsCodeDru  6 ปีที่แล้ว +5

      Да, к сожалению, в коде примера есть упущения, но судя по тому, что вы их находите - они на пользу идут :) т.к. умение находить баги дорогого стоит ;)

    • @ms_shifu7047
      @ms_shifu7047 5 ปีที่แล้ว +5

      ​@@Vladislav4er не совсем корректно, т.к. если что-то не так с email, то не будет сообщения.
      Вместо model.addAttribute("passwordError", "Passwords are different!"); пишем о так вот:
      bindingResult.addError(new FieldError("user", "password", "Passwords are different!"));
      Пояснение: добавляем ошибку в bindingResult ручками, после чего данная ошибка успешно ловится в следующем блоке if.
      P.s. это я сам придумал, так что если че, на меня не ссылаться.

  • @ОлегОрловский-д6м
    @ОлегОрловский-д6м ปีที่แล้ว

    Если у кого-то не появляются ошибки, хотя в представление они попадают, уберите редирект из контроллера добавления пользователя

  • @vladislavkhramykh2829
    @vladislavkhramykh2829 5 ปีที่แล้ว +2

    Возьмём сразу инвалид) орнул чёт) лучший в мире за работой

  • @kirilltseitlin3145
    @kirilltseitlin3145 5 ปีที่แล้ว +6

    После добавления функционала с password confirmation. возникла проблема: После регистрации переходя по линку активации выпадала 500 ошибка + то что поле password2 не может быть пустым. В итоге перенес конфирмацию пароля на сторону клиента (java script).
    Кто нибудь сталкивался с подобной проблемой? Если да то, решили? И как?
    Всем спасибо.

    • @ЕвгенийРидецкий-ь7р
      @ЕвгенийРидецкий-ь7р 5 ปีที่แล้ว +1

      Можно добавить в метод активации типа user.setPassword2(user.getPassword()); И валидация не падает и активируется юзер отлично

    • @Ро́бертДжеймсФишер-в5е
      @Ро́бертДжеймсФишер-в5е 4 ปีที่แล้ว

      да сталкивался и пока не решил)))

    • @Ро́бертДжеймсФишер-в5е
      @Ро́бертДжеймсФишер-в5е 4 ปีที่แล้ว

      @@ЕвгенийРидецкий-ь7р не работает ваш вариант,везде где возможно попробовал сделать setPassword2 все равно та же ошибка

  • @Алексей-о3е1ф
    @Алексей-о3е1ф 5 ปีที่แล้ว

    Отличный курс! Спасибо автору.

  • @goodman2156
    @goodman2156 2 ปีที่แล้ว +1

    Откуда на 7:39 появился textError?
    Мы же не передавали строку в модель
    Это нужно было пояснить: это крайне неочевидный вывод

    • @goodman2156
      @goodman2156 2 ปีที่แล้ว +1

      Я понял: это из класса ControllersUtil название атрибута модели
      Но хотя бы в двух словах надо было об этом рассказать, епта

  • @danilkashtan
    @danilkashtan 5 ปีที่แล้ว +1

    Подскажите, пожалуйста, как добавить extension в MySQL? Без него приложение не дает зайти даже под админом, пишет "Encoded password does not look like BCrypt"

  • @D.P._
    @D.P._ 5 ปีที่แล้ว

    Спасибо! Отличный и лаконичный материал!

  • @ryzenka_s
    @ryzenka_s 4 ปีที่แล้ว +3

    Можливо комусь знадобиться) не спрацьовувала валідація на додаванні повідомлення, проблема була у версії hibernate-validator у pom.xml, для 7 версії не працювало, змінивши на 6 (6.1.5.Final якщо точніше) все стало ок

  • @lanalystan9581
    @lanalystan9581 4 ปีที่แล้ว +1

    для mysql - создайте админа как простого юзера через запущенную программу (пароль зашифруется), а затем в скрипте установите роль админа через insert.У меня так получилось выйти из ситуации... Может есть лучше решение?
    Автору огромное спасибо!

  • @MA-wi8qd
    @MA-wi8qd 5 ปีที่แล้ว +2

    после создания файла миграции запуск приложения выдает следующую ошибку:
    Caused by: org.postgresql.util.PSQLException: ОШИБКА: функция crypt(character varying, text, integer) не существует
    Hint: Функция с данными именем и типами аргументов не найдена. Возможно, вам следует добавить явные приведения типов. Модуль pgcrypto установлен в моей БД. Как исправить ошибку?

    • @MA-wi8qd
      @MA-wi8qd 5 ปีที่แล้ว

      оказ-ся у меня была опечатка: вместо update usr set password=crypt(password, gen_salt('bf',8)); у меня было написано update usr set password=crypt(password, gen_salt('bf'),8);

  • @mrMarseleene
    @mrMarseleene 5 ปีที่แล้ว +11

    Если у кого-то такая ошибка: Error creating bean with name 'getPasswordEncoder': Requested bean is currently in creation: Is there an unresolvable circular reference?
    Я добавил @Lazy перед @Autowired
    private PasswordEncoder passwordEncoder; в websecurityconfig, теперь работает.
    Год назад по этим гайдам учился, было без ошибок. Сейчас версия spring 2.2.1.
    В чем проблема, почему сейчас он циклится, а до этого без @Lazy работал?

    • @alisaromanova3933
      @alisaromanova3933 4 ปีที่แล้ว

      Хз в чем дело, но мне помог твой коммент

    • @Twinky009
      @Twinky009 4 ปีที่แล้ว

      Спасибо, от души!!!)))))))))

    • @Booruvcheek
      @Booruvcheek 4 ปีที่แล้ว

      Спасибо за подсказку.
      Проект с гитхаба компилируется, но не запускается, ругается что зациклился, ошибки такие - pastebin.com/NEEVEraN
      Я сделал немного по-другому, как советовали в другом комменте, вынес
      @Bean
      public PasswordEncoder getPasswordEncoder() {
      return new BCryptPasswordEncoder(8);
      }
      в отдельный класс BeanConfig (в com.example.sweater.config).
      Честно говоря, именно за такие вещи мне Spring и не нравится - он делает всё за тебя (например создаёт объекты, инициализирует поля твоих объектов), но при этом если что-то сломалось, зачастую просто не знаешь как найти корень проблемы.
      Понимаю что здесь это прозвучит крамолой, но мне нравится понимать как работает моя программа! Понимать кто кого вызывает, как происходит инициализация, где главный цикл, иметь возможность отлаживать по шагам. Spring лишает меня всего этого.

  • @qr46654
    @qr46654 4 ปีที่แล้ว +1

    Расскажите пожалуйста - защититься от атак типа SQL-Injection?

  • @noyklgd4403
    @noyklgd4403 6 ปีที่แล้ว +5

    в конце улыбнуло)))

    • @letsCodeDru
      @letsCodeDru  6 ปีที่แล้ว +4

      Капля моих закулисных страданий

  • @ВикторИвунин
    @ВикторИвунин 6 ปีที่แล้ว +1

    Небольшой вопрос, стоит ли создавать DTO объекты или валидацию прямо в модели делать?

  • @ЕгорКозлов-у5ж
    @ЕгорКозлов-у5ж 6 ปีที่แล้ว +7

    Добрые люди! Подскажите кто-нибудь, что нужно в файле миграции V3__Encode_passwords прописывать для MySQL. Все интернеты прошарил, пробовал писать aes_encode, encode не помогло.

    • @Igor_Litvinyuk
      @Igor_Litvinyuk 6 ปีที่แล้ว

      Тоже интересует

    • @Igor_Litvinyuk
      @Igor_Litvinyuk 6 ปีที่แล้ว +1

      Ничего не нашел по этому поводу. Поэтому удалил миграцию V2 с админом и в UserService добавил условие в метод по добавлению юзера, если пользователей еще нету, то первому дать роль админа, иначе давать роль только юзер. Это первое, что пришло в голову, но ведь работает. Возможно автор еще что-то посоветует

    • @alexandrmakarevich5334
      @alexandrmakarevich5334 6 ปีที่แล้ว +7

      Как вариант попробуйте миграцию V2 сделать такой
      -- user - admin,password - admin
      insert into usr (id, username, password, active, email)
      values(
      1,
      'admin',
      '$2a$08$IJIxzOQ3s5Ihxz9LlAQXx.R4OfwgVzrmM8Daj6zH3t5S0ULA9TtG6',
      true,
      'тут необходимо прописать email админа,иначе валидация не пройдёт'
      );
      insert into user_role (user_id, roles)
      values(1, 'USER'),
      (1, 'ADMIN');

    • @lumea-arboris
      @lumea-arboris 6 ปีที่แล้ว +3

      Спасибо, сделал как вы написали - все получилось!!! Ваш комментарий - решение для MySQL

    • @sharabicus5482
      @sharabicus5482 6 ปีที่แล้ว +1

      Я сделал так: update myapp.usr set password = if(username != 'admin', MD5(password), password);

  • @АлександрХромов-р5т
    @АлександрХромов-р5т 6 ปีที่แล้ว +2

    В миграции V3 есть строка create extension if not exists pgcrypto; для выполнения которой пользователю баз нужны права superuser в БД. Мне кажется это не есть хорошо. Как можно по другому сделать?

    • @letsCodeDru
      @letsCodeDru  6 ปีที่แล้ว +2

      заранее установить расширение на сервере БД

  • @the_toxic
    @the_toxic 6 ปีที่แล้ว +2

    Можно уточнить, в чем разница между атрибутами Map model и Model model. ?
    Оба выполняют одну и ту-же роль по сути. Только способы наполнения разные.
    Вообще самая магическая часть для меня - это атрибуты методов контроллеров.

    • @letsCodeDru
      @letsCodeDru  6 ปีที่แล้ว

      Не велика разница, на самом деле: и там и тут коллекция ключ-значение. Model чуть каноничней

    • @Евгений-ч9к2ф
      @Евгений-ч9к2ф 4 ปีที่แล้ว

      @Пожилой Программист дай ссылку

  • @sergeyzaharov4153
    @sergeyzaharov4153 5 ปีที่แล้ว +1

    Автору заранее спасибо за видео. Очень подробно и ясно. Но столкнулся с такой вот ошибкой "Error creating bean with name 'getPasswordEncoder': Requested bean is currently in creation: Is there an unresolvable circular reference?" - хотя полностью проходил по вашему туториалу. Можете описать решение данной проблемы

  • @qr46654
    @qr46654 4 ปีที่แล้ว +1

    Пожалуйста расскажите - если указать значение коэффициента надежности шифрования пароля в application.preferences, то как его оттуда получить?
    Например, выражение @Value("passwort.strength") int passwordStrength; - возвращает null???

    • @nelsonnetru
      @nelsonnetru 9 หลายเดือนก่อน

      Потому что из application.preferences она берется как String, а потом ее надо распарсить в Integer:
      @Value("${passwort.strength}")
      String strength;
      @Bean
      public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(Integer.parseInt(strength)); }

  • @johnrambo6996
    @johnrambo6996 3 ปีที่แล้ว

    message добавляется в model и без model.addAttribute("message", message); это новая фишка спринга, которой не было при создании видео или я что-то не так понял?
    хотя автор обнуляет message, если создание прошло успешно. т.е. оно есть в модели изначально. зачем тогда строка model.addAttribute("message", message); ? ф

  • @ИльяЗавертайло
    @ИльяЗавертайло 4 ปีที่แล้ว +2

    столкнулся с проблемой, не отображаются ошибки в шаблонах. При этом в модели инвалиды есть, то есть они приходят, но не появляются. При этом все делал именно так, как на видео.

    • @nurte4
      @nurte4 4 ปีที่แล้ว

      в main controller в методе add добавил метод model.mergeAttributes(errorMap); проверь )

    • @yeszimin
      @yeszimin 4 ปีที่แล้ว

      Проверь, в MainController для add должен быть "return "main";", без редиректов.

    • @daniilkrizhanovsky2523
      @daniilkrizhanovsky2523 2 ปีที่แล้ว

      @@yeszimin тогда при обновлении страницы будет повторная отправка формы.
      Я нашёл не совсем красивое решение:
      в MainController.addMessage добавить принимаемый параметр RedirectAttributes
      а дальше в проверке условия bindingResult.hasErrors() заменяем то, что было в видео на то, что ниже
      Map errorsMap = ControllerUtils.getErrors(bindingResult)
      redirectAttributes.addFlashAttribute("message",message);
      if(errorsMap!=null && !errosMap.isEmpty())
      {
      errorsMap.forEach(redirectAttributes::addFlashAttribute);
      }

    • @daniilkrizhanovsky2523
      @daniilkrizhanovsky2523 2 ปีที่แล้ว

      в таком случае можно сохранить redirect и ошибки будут переданы

  • @farallel6796
    @farallel6796 6 ปีที่แล้ว +1

    Так же очень было бы интересно в дополнение к загрузке файлов на сервер, посмотреть как будет выглядеть загрузка файлов таким образом, когда мы заранее не знаем сколько картинок и в каком месте между текстом они будут находится? Мы например создаем что-то вроде новости, в которой идут отдельные абзацы с текстом и между ними будут картинки. Сколько будет этих абзацев и картинок мы заранее не знаем. Меня на самом деле устроит даже ссылка на толковый ресурс, где описано как это сделать на спринге, но в идеале конечно было бы посмотреть на это в вашем исполнении.) Хотя такими темпами, внедряя все пожелания подписчиков этот проект очень скоро разрастется до размеров Facebook.)

    • @letsCodeDru
      @letsCodeDru  6 ปีที่แล้ว

      Признателен за обратную связь, но пожалуйста, не надо дублировать сообщения)))
      Дублирую ответ:
      Это уже не про java, это уже больше про JavaScript. Конечно, можно прикрутить визуальный редактор и отдать ему всё на откуп, но обычно это работает очень плохо.
      В целом же, работу с такими редакторами обязательно рассмотрю :)

  • @medweather
    @medweather 5 ปีที่แล้ว +1

    Крутой чувак!😎

  • @АлександрХлопотнов-ш4о
    @АлександрХлопотнов-ш4о 5 ปีที่แล้ว +2

    Забавная ошибка вылезла в видео:
    когда мы в форме регистрации и имеем пустые поля , нажимаем создать нового юзера, и у нас в navbar вылезает вкладка Profile , как будто мы прошли валидацию на сайте, но мы по-прежнему имеем статус "unknown".
    Спасибо за уроки, всё очень классно.

    • @АлександрХлопотнов-ш4о
      @АлександрХлопотнов-ш4о 5 ปีที่แล้ว +2

      Решается это дело в navbar.ftl дописанием к условию если юзер авторизован и не имеет имя Guest

    • @Braklord
      @Braklord 4 ปีที่แล้ว +1

      Profile

  • @МихаилСмирнов-к3р
    @МихаилСмирнов-к3р 6 ปีที่แล้ว

    Если по одному полю срабатывает сразу два условия валидации, как в этом случае получить список ошибок?
    При использовании коллекции Map выскакивает ошибка, т.к. появляется второй дублирующий ключ.

  • @alexdavydov3311
    @alexdavydov3311 5 ปีที่แล้ว

    У меня почему то не работала проверка на совпадение паролей пока не добавил в условие return "registration"; Может я что-то пропустил?
    @PostMapping("/registration")
    public String addUser(@Valid User user, BindingResult bindingResult, Model model){
    if (user.getPassword() != null && !user.getPassword().equals(user.getPassword2())) {
    model.addAttribute("passwordError", "Passwords are different!");
    return "registration";
    }
    if (bindingResult.hasErrors()) {
    Map errors = ControllerUtils.getErrors(bindingResult);
    model.mergeAttributes(errors);
    return "registration";
    }
    if (!userService.addUser(user)) {
    model.addAttribute("usernameError", "User exists!");
    return "registration";
    }

    return "redirect:/login";
    }

    • @insurg
      @insurg 4 ปีที่แล้ว

      в таком случае если пароли будут не совпадать, то ты не узнаешь о других возможных ошибках валидации. лучше написать так:
      @PostMapping("/registration")
      public String addUser(@Valid User user, BindingResult bindingResult, Model model){
      if (user.getPassword() != null && !user.getPassword().equals(user.getPassword2())) {
      model.addAttribute("passwordError", "Passwords are different!");
      }
      if (bindingResult.hasErrors()) {
      Map errors = ControllerUtils.getErrors(bindingResult);
      model.mergeAttributes(errors);
      }
      boolean containAnyError = model.asMap().keySet().stream()
      .anyMatch(key -> key.contains("Error"));
      if (containAnyError) {
      return "registration";
      }
      if (!userService.addUser(user)) {
      model.addAttribute("usernameError", "User exists!");
      return "registration";
      }

      return "redirect:/login";
      }

  • @nikitaantonenko3287
    @nikitaantonenko3287 5 ปีที่แล้ว

    спасибо большое, очень полезное видео!))

  • @alexgusev5753
    @alexgusev5753 5 ปีที่แล้ว +2

    Огромное спасибо за уроки!
    Вопрос: Если инжектить бины через конструктор, возникает круговая зависимость userService и webSecurityConfig, которая не даёт запустить приложение. Таким образом в данной ситуации можно использовать только DI через поля?

    • @JordanSaddam
      @JordanSaddam 5 ปีที่แล้ว +1

      У меня такая круговая зависимость получилась из-за бина encoder в методе класса webSecurityConfig, спринг не может создать encoder до создания webSecurityConfig. Нужно вынести метод создания бина encoder, например, статический метод(не уверен насколько это нормальная практика).

    • @inginiir
      @inginiir 4 ปีที่แล้ว +1

      ещё можно поставить аннотацию @lazy

  • @Евгений-ч9к2ф
    @Евгений-ч9к2ф 4 ปีที่แล้ว

    а валидация также отрабатывает при любом сохранении сущности в базу а не только в ендпоинтах?

  • @ELISEY_OSADCHY
    @ELISEY_OSADCHY 2 ปีที่แล้ว

    У кого вылезает ошибка после шифрования паролей Could not commit jpa transaction; nested exception is javax.persistence.rollbackexception: error while committing the transaction. Если вы ставили @Size(max=значение), и значение меньше 60, то поставьте 60, потому что Bcrypt хеширует пароль и сохраняет его как случайные 60 символов, что нарушает максимальные ограничения на размер. Мне это помогло.

  • @DarthJaxxFather
    @DarthJaxxFather 6 ปีที่แล้ว +3

    А активация логина у всех работает localhost:8080/activate/{code}? Ссылается на ошибку валидации в классе User. На экране 500, в логах 'HHH000346: Error during managed flush [Validation failed for classes [com.darthjaxx.sweater.domain.User] during update time for groups [javax.validation.groups.Default, ]"

    • @letsCodeDru
      @letsCodeDru  6 ปีที่แล้ว +4

      Да, пропустил я этот экран, косяк :( в следующем видео будет правка
      Спасибо, что не только следите за мной, но и сообщаете об ошибках! :)

    • @notUnclePetro
      @notUnclePetro 6 ปีที่แล้ว

      да, из-за того, что наше поле password2 помечено аннотацией @NotBlank (@NotEmpty), а мы пытаемся сделать save() в репозиторий юзера с пустым полем password2. поэтому падает с ошибкой валидации

    • @detson_
      @detson_ 5 ปีที่แล้ว

      @@notUnclePetroСтранно, я думал валидация работает при попытке внесении в поле null, а не при попытке сохраниться null данные в базу данных

  • @timuris5820
    @timuris5820 5 ปีที่แล้ว +1

    Кто-то использует H2 базу данных? Если да, помогите с миграцией кодировки паролей, молю.

  • @Евгений-ч9к2ф
    @Евгений-ч9к2ф 4 ปีที่แล้ว +1

    странная ошибка при сохранении пользователя в базу:
    после строк
    user.setPassword("1");
    user.setPasswordV("1");
    userRepo.save(user);
    Вылетает
    javax.validation.ConstraintViolationException: Validation failed for classes [com.example.app.domain.User] during update time for groups [javax.validation.groups.Default, ]
    List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='Password confirmation cannot be empty', propertyPath=passwordV, rootBeanClass=class com.example.app.domain.User, messageTemplate='Password confirmation cannot be empty'}
    ]
    Те вадидация происходит при добавлении в базу хибернейтом, но от жалуется на поле которое якобы не заполнено но оно очевидно же что заполненное.
    Я не знаю как это можно объяснить, но было бы интересно разобраться почему так

    • @Евгений-ч9к2ф
      @Евгений-ч9к2ф 4 ปีที่แล้ว

      короче у хибернейта есть косяк - он валидирует транзиентные поля сущностей при сохранении в бд если сущности в группе по умолчанию (если группа не указана в анннатации). Решение - назначить кастомную групппу:
      @NotBlank(message = "Password confirmation cannot be empty", groups = TransientField.class)
      // @NotBlank(message = "Password confirmation cannot be empty")
      private String passwordV;
      public interface TransientField {
      }
      в пропертис прописать : spring.jpa.properties.javax.persistence.validation.group.pre-persist=com.example.app.domain.TransientField
      не тогда сообщение об ошибке не выводится, чтото с группами в аннотации не так..

    • @Евгений-ч9к2ф
      @Евгений-ч9к2ф 4 ปีที่แล้ว

      еще это spring.jpa.properties.javax.persistence.validation.mode=none работает

    • @Евгений-ч9к2ф
      @Евгений-ч9к2ф 4 ปีที่แล้ว +3

      вот нормальное решение:
      добавить
      @PostLoad
      private void postLoadFunction1(){
      this.password2 = this.password;
      }
      в entity юзера.

    • @Braklord
      @Braklord 4 ปีที่แล้ว

      Если бы ещё кто-то объяснил сей феномен...
      Я тоже добавил в User.class
      @Transient
      @NotBlank(message = "Password confirmation cannot be empty", groups = NoDefault.class)
      private String password2;
      И добавил в *.*.domain интерфейс public interface NoDefault {}
      Хотя бы теперь работает подтверждение аккаунта с помощью кода активации

    • @Romigo4
      @Romigo4 4 ปีที่แล้ว

      @@Евгений-ч9к2ф спасибо тебе! наткнулся на такую же проблему, не понимал что происходит. А почему у автора не было такой ошибки ? версии зависимостей другие ?

  • @oleksiihlushenok8025
    @oleksiihlushenok8025 6 ปีที่แล้ว +1

    а можно пояснить в чём разница между Map и Model, кроме различий в названиях методов ?

  • @alexpanasyuk4696
    @alexpanasyuk4696 5 ปีที่แล้ว +1

    10:42 работает и без этой строчки.Это я где то ошибся или вы? ps: Модель прилетает пустая.

  • @kirillkotenok6382
    @kirillkotenok6382 5 ปีที่แล้ว

    Отличные уроки)
    Не кто не знает почему когда вводишь все данные и при этом разные пароли создаётся новый пользователь, если на пример не ввести имейл и при этом ввести разные пароли, то всё работает и выдаёт сообщение о том что пароли разные?

  • @inginiir
    @inginiir 4 ปีที่แล้ว

    подскажите пжл, после того как в контроллере поменяли выдергивание полей message из реквеста на объект message с аннотацией @валид где происходит инициализация этого объекта?

    • @andreiivanov3683
      @andreiivanov3683 4 ปีที่แล้ว

      Тоже не понял? Если разобрались может поясните?

  • @СергейВолков-ф1м
    @СергейВолков-ф1м 6 ปีที่แล้ว

    А при изминение пароля в profile в бд разве не будут сохраняться незашифрованые пароли?

  • @Ро́бертДжеймсФишер-в5е
    @Ро́бертДжеймсФишер-в5е 4 ปีที่แล้ว +1

    Подскажите кто нибудь на каком этапе происходит валидация ,я уже везде попробовал задать поле password2 чтобы при валидации оно не было пустым,но у меня все равно при изменении пароля выходит одно и тоже сообщение про ошибку [com.example.sweater.domain.User] during update time for groups [javax.validation.groups.Default, ]
    List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='Password confirmation cannot be empty', propertyPath=password2, rootBeanClass=class com.example.sweater.domain.User, messageTemplate='Password confirmation cannot be empty'}

    • @Ро́бертДжеймсФишер-в5е
      @Ро́бертДжеймсФишер-в5е 4 ปีที่แล้ว

      Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction] with root cause

    • @Ро́бертДжеймсФишер-в5е
      @Ро́бертДжеймсФишер-в5е 4 ปีที่แล้ว

      и именно фиксируется линия в методе updateProfile в классе UserService где я сохраняю пользователя в базу,то есть обнавляю userRepo.save(user);

    • @romanl4089
      @romanl4089 ปีที่แล้ว

      @@Ро́бертДжеймсФишер-в5е , привет и далекого будущего ) Ты нашел ответ (если еще помнишь)? С тем же бьюсь пока безрезультатно.

    • @Ро́бертДжеймсФишер-в5е
      @Ро́бертДжеймсФишер-в5е ปีที่แล้ว

      @@romanl4089 привет))сори я не помню, но решил по моему

    • @romanl4089
      @romanl4089 ปีที่แล้ว +1

      @@Ро́бертДжеймсФишер-в5е , привет! Спасибо что отозвался! Я только что тоже сделал, посмотрев следующее видео автора, где он фиксит эту проблему.

  • @atg8798
    @atg8798 6 ปีที่แล้ว +1

    Когда жмешь "зарегистрироваться" не введя при этом совсем ничего ни в какие поля, выдает ошибку: java.lang.IllegalStateException: Duplicate key Password field cannot be empty. И указывает на класс ControllerUtils.

    • @atg8798
      @atg8798 6 ปีที่แล้ว

      Хотя у тебя в видео ты жмешь создать пользователя, не введя ничего и никаких проблем. У меня падает в общем такая херня.

    • @atg8798
      @atg8798 6 ปีที่แล้ว +3

      Проблема решена вот таким вот образом.
      static Map getErrors(BindingResult bindingResult) {
      Map result = new TreeMap();
      for (FieldError f : bindingResult.getFieldErrors()) {
      if (!result.containsKey(f.getField() + "Error")) {
      result.put(f.getField() + "Error", f.getDefaultMessage());
      }
      }
      return result;
      }

    • @atg8798
      @atg8798 6 ปีที่แล้ว

      Вот с этими лямбдами конечно проблемки, по моему код нихрена понятнее с ними не стал, а вот "по старому" очень все даже понятно что происходит.

    • @letsCodeDru
      @letsCodeDru  6 ปีที่แล้ว +2

      ну да, они не панацея. Где-то они помогают, а где-то лучше и без них)

  • @alekseyzhdanov6599
    @alekseyzhdanov6599 4 ปีที่แล้ว

    Спасибо за видос. Свою ошибку нашел)

  • @victormog
    @victormog 6 ปีที่แล้ว +6

    *Как быть пользователям MySQL?!* ;-)
    Есть устойчивое чувство, что, т.к. _'admin'_ - единственный пользователь, то может не городить огород с третьим файлом миграции (V3__), а добавить во второй (V2__) хэш пароля, сгенерированного заранее. Например тут: www.devglan.com/online-tools/bcrypt-hash-generator

    • @letsCodeDru
      @letsCodeDru  6 ปีที่แล้ว +1

      Как вариант

    • @YuretsUA
      @YuretsUA 5 ปีที่แล้ว

      Воспользовался твоим советом, вот только в миграцию V2 ничего вставить не удалось, получил ошибку контрольной суммы, в V3 добавил sql команду на изменение пароля. Но вопрос остается открытым, как прописать шифрование старых паролей для MySql

    • @KyivanEnjoyer
      @KyivanEnjoyer 5 ปีที่แล้ว

      @@YuretsUA тебе же дали сайт, где генерирует пароль, в чем проблема написать через update в mysql?

    • @YuretsUA
      @YuretsUA 5 ปีที่แล้ว +2

      @@KyivanEnjoyer В этом проблемы нет, но это в данном конкретном случаи, когда нужно изменить только один пароль. А в качестве обучения хотелось бы все-таки заморочиться и сделать по умному. Но в ряду отсутствия времени заморачиваться над шифрованием не стал, и использовал шифрование через сайт.

  • @mvlikhachev
    @mvlikhachev 5 ปีที่แล้ว

    Field 'id' doesn't have a default value - MySQL, воевал часов 5) Приложение запускалось, но ничего не добавлялось в БД. Проблема решилась как всегда просто) AUTO_INCREMENT нужно добавить к полям id в первой миграции) Может кому-то поможет

  • @MA-wi8qd
    @MA-wi8qd 5 ปีที่แล้ว

    Не могли бы вкратце пояснить что такое Bean? если он нужен только для того, что потом его можно было autowir-ить, то почему наш класс UserService, который не обозначен Bean, тоже можно autowir-ить?

    • @andreyomelchuk19
      @andreyomelchuk19 5 ปีที่แล้ว +4

      Начнем срывать покровы с самых базовых понятий Spring. Бин (bean) - это не что иное, как самый обычный объект. Разница лишь в том, что бинами принято называть те объекты, которые управляются Spring-ом и живут внутри его DI-контейнера. Бином является почти все в Spring - сервисы, контроллеры, репозитории, по сути все приложение состоит из набора бинов. Их можно регистрировать, получать в качестве зависимостей, проксировать, мокать и т.п. источник habr.com/ru/post/334448/

    • @Индахаус
      @Индахаус 5 ปีที่แล้ว

      @@andreyomelchuk19 красава, спсибо

  • @AlexandrKolomoets
    @AlexandrKolomoets 5 ปีที่แล้ว +1

    Материал просто супер! С друзьями начали по вашим урокам учить джаву! Все четко, ясно и ёмко! Есть проблема, при попытке залогиниться выдает "Bad credentials"! Создание нового пользователя проходит нормально, но залогиниться ни под новым ни под админом не выходит. Подскажите куда копать? Есть подозрение на шифрование...

    • @letsCodeDru
      @letsCodeDru  5 ปีที่แล้ว

      По месту смотреть надо. Разбирайтесь. Это единственный способ научиться кодить. :)

    • @AlexandrKolomoets
      @AlexandrKolomoets 5 ปีที่แล้ว

      @@letsCodeDru Я это понимаю) целый день ищу ошибку... Ночной кодинг сказывается(((

    • @vladzagRussia
      @vladzagRussia 5 ปีที่แล้ว

      Аналогичная проблема, уже весь код перекопал(

    • @AlexandrKolomoets
      @AlexandrKolomoets 5 ปีที่แล้ว

      @@vladzagRussia мне помогло добавление емейла в миграцию

  • @pavelniporka7648
    @pavelniporka7648 4 ปีที่แล้ว

    Спасибо дружище!!!

  • @yelamaan
    @yelamaan 5 ปีที่แล้ว +1

    Добрый день! Спасибо большое за уроки! Хотел спросить в следующих уроках покажут как сделать так что бы юзер без активации не мог логиниться в систему. А то вы научили как активацию делать а проверять нет)

    • @yelamaan
      @yelamaan 5 ปีที่แล้ว

      Я хотел спросить как исправить баг который позволяет логиниться в систему без активации после регистрации

    • @ДанилДенк
      @ДанилДенк 2 ปีที่แล้ว

      @@yelamaan Если актуально еще то - просто меняй переменную ACTIVE у юзера на тру только при подтверждении почты.

  • @Das.Kleine.Krokodil
    @Das.Kleine.Krokodil 2 ปีที่แล้ว

    Подскажите, что нужно внедрять через @Bean, а что создавать явно через new?
    Чем руководствоваться при принятии решения?

    • @nelsonnetru
      @nelsonnetru 9 หลายเดือนก่อน

      когда ты создаешь @Bean, то spring сразу создаст экземпляры этих классов и они будут жить в контексте твоего приложения, благодаря чему ты сможешь подтянуть этот экземпляр из любого другого класса через @Autowired. Поэтому, если тебе надо обработать, например, какой-то текст при помощи StringBuilder, то экземпляр этого класса не надо создавать через @Bean. Экземпляр StringBuilder логично будет создать через new, чтобы поработать с ним "здесь и сейчас" и забыть о нем.

    • @Das.Kleine.Krokodil
      @Das.Kleine.Krokodil 9 หลายเดือนก่อน

      @@nelsonnetru частично ответил

  • @adiletzhuzupbekov9530
    @adiletzhuzupbekov9530 5 ปีที่แล้ว

    Привет дорогой автор. Спасибо тебе огромное за проделанную работу. Я тут заметил маленькую логическую ошибку в котором я не способен разобраться. Как мы написали При регистрации если не вести майл но ввести разные пороли выдается ошибка о разности пороля, но если ввести разные пороли но ввести емайл. регистрация проходит...

    • @dmitrysomsin2117
      @dmitrysomsin2117 5 ปีที่แล้ว +1

      Я в проверку if (user.getPassword() != null && !user.getPassword().equals(user.getPasswordConfirmation())) { добавил return "registration";

  • @MegaErrors
    @MegaErrors 5 ปีที่แล้ว

    ДД. Каждый рас приходиться удалять бд что бы новый файл миграции заработал. Почему?

    • @mrMarseleene
      @mrMarseleene 5 ปีที่แล้ว

      application.properties поправил?

  • @РафаэльЯкупов-х4й
    @РафаэльЯкупов-х4й 4 ปีที่แล้ว +1

    Небольшой комментарий, контроллер работает отлично, даже если заменить Model на Map. И на счет порядка тоже, порядок важен только с валидируемой энтити и bindingResult(если после них поставить еще один RequestParam перед моделью для вьюхи, то ничего не сломается).

  • @notlocalatall8709
    @notlocalatall8709 5 ปีที่แล้ว

    Подскажите кто-нибудь, пожалуйста а зачем мы отправляем ссылку на почту для поддтверждения, если и так пользователь активируется при регистрации?

    • @andreyomelchuk19
      @andreyomelchuk19 5 ปีที่แล้ว

      пользователь активен, но не прошел активацию по почте (извините за тавтологию), ведь перейдя по ссылке, у него поле activationCode станет равным null и по условию мы его пропустим

    • @notlocalatall8709
      @notlocalatall8709 5 ปีที่แล้ว

      @@andreyomelchuk19 Спасибо. Но в чём смысл, если и без перехода по ссылке вся функциональность доступна?

    • @javastream9414
      @javastream9414 5 ปีที่แล้ว +1

      @@notlocalatall8709, можете ограничить сервис для пользователей, не подтвердивших почту.

  • @KyivanEnjoyer
    @KyivanEnjoyer 5 ปีที่แล้ว +1

    Произошла интересная ошибка:
    The dependencies of some of the beans in the application context form a cycle:
    ┌─────┐
    | webSecurityConfig defined in file [C:\Users\%user%\sweater\target\classes\com\example\sweater\config\WebSecurityConfig.class]
    ↑ ↓
    | userService defined in file [C:\Users\%user%\sweater\target\classes\com\example\sweater\service\UserService.class]
    └─────┘
    вроде как понятно, а вроде и не понятно -_- Так бесит, когда в таком же коде у людей работает, а у меня нет.
    Кто знает как пофиксить?)

    • @KyivanEnjoyer
      @KyivanEnjoyer 5 ปีที่แล้ว

      Пофиксил изменив все классы на @Autowired вместо private final + constructor, но почему-то в первый раз при регистрации пользователя у меня выдало ошибку java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'PRIMARY',
      а в следующий раз заработало

    • @sergeyzaharov4153
      @sergeyzaharov4153 5 ปีที่แล้ว

      @@KyivanEnjoyerСтолкнулся с той же ошибкой. Ведсюсюрити говорит что нужен изерСервис а сервис наоборот. Пока не пофиксил. Как подробнее фиксили данную проблему если я так же через @Awtowired делал и через @Bean как в самом видео и ловлю данную ошибку

    • @KyivanEnjoyer
      @KyivanEnjoyer 5 ปีที่แล้ว

      @@sergeyzaharov4153 честно уже не помню, но вроде просто в обоих классах где у меня было через конструктор - поменял на @Autowired и обычное private поле(вроде в конфиге и сервиса)

    • @wodzimierzletov2990
      @wodzimierzletov2990 5 ปีที่แล้ว +7

      Для того, чтобы пофиксить эту ошибку - нужно в классе WebSecurityConfig сделать бин getPasswordEncoder() статическим. Тогда по правилам java он будет подгружаться раньше, чем конструктор и не будет никаких проблем.

    • @wodzimierzletov2990
      @wodzimierzletov2990 5 ปีที่แล้ว

      @@sergeyzaharov4153 Думаю, ваша проблема может решиться таким же образом

  • @Алексей-о3е1ф
    @Алексей-о3е1ф 5 ปีที่แล้ว +1

    Ctrl + Alt + M Поместить в метод

  • @alexeysharandin7364
    @alexeysharandin7364 5 ปีที่แล้ว

    Как всегда замечательно. Спасибо.
    Осталось выяснить где Spring врапает throw new UsernameNotFoundException("User not found"); и как выводить то что кинул

    • @ms_shifu7047
      @ms_shifu7047 5 ปีที่แล้ว

      Так таки удалось выяснить?

    • @РоманКотович-в9ж
      @РоманКотович-в9ж 5 ปีที่แล้ว +1

      @@ms_shifu7047 как вариант можете создать свой эксепшен, наследуясь от AuthenticationException.
      -----------------------------------------------------------
      public class UserNotFoundInDataBase extends AuthenticationException {
      public UserNotFoundInDataBase(String msg) {
      super(msg);
      }
      }
      -----------------------------------------------------------
      И в методе loadUserByUsername вместо UsernameNotFoundException поставить свой, со своим месседжем.
      -----------------------------------------------------------
      if(user == null){
      throw new UserNotFoundInDataBase("Пользователь не найден");
      }
      -----------------------------------------------------------
      Который и увидит юзер.

    • @ФомаКиняев-ж2ш
      @ФомаКиняев-ж2ш 3 ปีที่แล้ว

      @@РоманКотович-в9ж спс

  • @ЕвгенийХодзицкий-с7и
    @ЕвгенийХодзицкий-с7и 6 ปีที่แล้ว

    Мне интересно, как ты зарегаешься под админом, когда задеплоишь это все. Или просто в sql инсерт будет?

    • @4val0v
      @4val0v 6 ปีที่แล้ว

      либо sql либо первому пользователю в бд давать админ права

    • @letsCodeDru
      @letsCodeDru  6 ปีที่แล้ว +2

      Так в предыдущем же видео я показал, как админка создать. Делаем миграцию, в которой создаём админа, пароль в скрипте подкладываем уже захэшированный

  • @farruxmasharipov6624
    @farruxmasharipov6624 6 ปีที่แล้ว

    А можно ли зашифровать имя пользователя с помощью BCryptPasswordEncoder?

    • @letsCodeDru
      @letsCodeDru  6 ปีที่แล้ว +1

      ну по идее можно. Не вижу необходимости, но если хочется - не стоит себе отказывать)))
      (на всякий напомню, что это не честное шифрование, а хэширование, т.е. необратимое шифрование и "расшифровать" обратно будет невозможно)

  • @caffeinejavacode1475
    @caffeinejavacode1475 5 ปีที่แล้ว +2

    Чет я не понял зачем два поля password

    • @krab9512
      @krab9512 4 ปีที่แล้ว

      Для проверки правильности введенного пароля с паролем из бд

  • @aleksei4604
    @aleksei4604 4 ปีที่แล้ว

    the best!

  • @alekseygromov8994
    @alekseygromov8994 3 ปีที่แล้ว +1

    Сам несколько раз находил решения в комментах, пришло мое время помочь.
    У кого вылетает IllegalStateException Duplicate Key при выводе сообщений об ошибках, у кого загорается красная рамочка, но не выводятся сообщения об ошибке, вам сюда.
    1я ошибка. Возникает из-за того, что мы по одному ключу (полю класса) имеем несколько сообщений об ошибке.
    Я это решил следующим образом:
    static Map getErrors(BindingResult bindingResult) {
    //хранит по каждому ключу(полю) несколько сообщений об ошибке
    Map allErrors = new HashMap();
    for (FieldError error : bindingResult.getFieldErrors()) {
    //ключ для Map
    String key = error.getField() + "Error";

    if (allErrors.containsKey(key)) {
    //добавляем по этому ключу новое сообщение с ошибкой
    allErrors.get(key).add(error.getDefaultMessage());
    } else {
    allErrors.put(key, new ArrayList(Arrays.asList(error.getDefaultMessage())));
    }
    }
    return allErrors;
    }
    И соответственно на view выводить в листах сообщения об ошибках.
    2я ошибка. У меня появилось отображение сообщений после того, как я перенес блок вывода сообщений внутрь div`а .input-group, т.е. блок расположен сразу после закрытия тега input`а.
    Надеюсь кому-то поможет в 2024.

    • @justbelieveinmyself
      @justbelieveinmyself ปีที่แล้ว

      БОЖЕ ТЫ МОЙ СПАСИТЕЛЬ 2 ОШИБКА) Огромное спасибо, что написал!!!

  • @global_silence2623
    @global_silence2623 6 ปีที่แล้ว

    Я думал здесь будет валидация по активационному коду)) Ну ладно, в принципе я добавил костыль в loadUserByUserName - написал там, что если имя пользователя и ключ активации не null, то возвращаем null. Позже мб оформлю его как следует.

    • @letsCodeDru
      @letsCodeDru  6 ปีที่แล้ว +1

      Я только показываю направление, как реализовывать - Отдаю вам на откуп. Если просто перелицовываать код с видео в редактор - ничему не научитесь

    • @global_silence2623
      @global_silence2623 6 ปีที่แล้ว +2

      Да это понятно)) По ходу делаю какие-то свои вставочки, читаю документацию. Убрал кстати кнопку sign out, если пользователь unknown. Вопрос такой, а где почитать про эти самые переменные такие чудные Session.SPRING_SECURITY_CONTEXT
      Session.SPRING_SECURITY_LAST_EXCEPTION

  • @laman4183
    @laman4183 3 ปีที่แล้ว

    ЛААААААААААААААААЙК

  • @joizjy
    @joizjy 5 ปีที่แล้ว +1

    ппц поставил в генерации id идентити и просрал 2 дня) надо курить базы

  • @ANDREYQIWS
    @ANDREYQIWS 4 ปีที่แล้ว

    Это для MySQL
    Ну у меня в
    V1
    create table hibernate_sequence (next_val bigint) engine=InnoDB;
    insert into hibernate_sequence values ( 2 );
    insert into hibernate_sequence values ( 2 );
    create table message (
    id bigint not null auto_increment,
    filename varchar(255),
    tag varchar(255),
    text varchar(2048) not null,
    user_id bigint,
    primary key (id)
    ) engine=InnoDB;
    create table user_role (
    user_id bigint not null,
    roles varchar(255)
    ) engine=InnoDB;
    create table usr (
    id bigint not null auto_increment,
    activation_code varchar(255),
    active bit not null,
    email varchar(255),
    password varchar(255) not null,
    username varchar(255) not null,
    primary key (id)
    ) engine=InnoDB;
    alter table message
    add constraint message_user_fk
    foreign key (user_id) references usr (id);
    alter table user_role
    add constraint user_role_user_fk
    foreign key (user_id) references usr (id);
    V2
    insert into usr (id, username, password, active)
    values (1, 'admin', '12345', true);
    insert into user_role (user_id, roles)
    values (1, 'USER'), (1, 'ADMIN');
    V3
    update usr set password = MD5(password);
    И В WebSecurityConfig нужно в Bean сделать так
    @Bean
    public PasswordEncoder getPasswordEncoder() {
    return new MessageDigestPasswordEncoder("MD5");

    • @goodman2156
      @goodman2156 2 ปีที่แล้ว

      MessageDigestPasswordEncoder - устаревший метод
      Хотя бы за это спасибо, для mysql заработало

  • @adiletzhuzupbekov9530
    @adiletzhuzupbekov9530 3 ปีที่แล้ว

    кто разобрался c thymeleaf ???

    • @dmitriylebedev651
      @dmitriylebedev651 3 ปีที่แล้ว

      Вот для текста сообщения:




      Text Error

  • @mrMarseleene
    @mrMarseleene 6 ปีที่แล้ว

    решил сделать так, чтобы, если код не активирован по мылу - выводится ошибка(активируйте емаил). Выходит Bad credatials, как ее заменить, долго не могу решить проблему, поэтому спрашиваю. п.с. Спасибо за уроки, респект!

    • @Nikita-hu9bk
      @Nikita-hu9bk 5 ปีที่แล้ว

      Ну что? Нашел?)

    • @mrMarseleene
      @mrMarseleene 5 ปีที่แล้ว

      @@Nikita-hu9bk Нашел, но уже не помню как решил) Если надо могу постараться вспомнить.

    • @Nikita-hu9bk
      @Nikita-hu9bk 5 ปีที่แล้ว

      @@mrMarseleene Было бы здорово, если бы ты вспомнил. Ибо я что-то ничего не нашёл(Видимо, плохо искал, раз ты нашёл).

    • @mrMarseleene
      @mrMarseleene 5 ปีที่แล้ว +1

      @@Nikita-hu9bk В метод loadUserByUsername из UserService я добавил новое исключение
      public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, LockedException
      LockedException из org.springframework.security.authentication;
      и написал
      if (user.getActivationCode() != null ) {
      throw new LockedException("email not activated");
      }

    • @mrMarseleene
      @mrMarseleene 5 ปีที่แล้ว

      @@Nikita-hu9bk чего я только не испробовал, у кого только не спрашивал, пару недель точно потратил на такой пустяк))

  • @nailtagiyev6340
    @nailtagiyev6340 2 ปีที่แล้ว

    А как быть с MySQL?

    • @nelsonnetru
      @nelsonnetru 9 หลายเดือนก่อน

      я так понял, что у MySQL нет расширения BCrypt, поэтому V3__Encode_passwords.sql не надо создавать, а зайти на bcrypt online, сгенерировать хэш пароля и указать его в V2__Add_admin.sql

  • @rhythmicpulse2760
    @rhythmicpulse2760 2 ปีที่แล้ว

    У меня была 500-я ошибка: неверный пароль или пользователь, т.к. Яндекс заблокировал почту, предположив что я спамер. Пришлось на почте и в пропертис пароль поменять и заработало!)