За последние 24 часа нас посетили 22735 программистов и 1269 роботов. Сейчас ищут 764 программиста ...

Как правильно валидировать формы?

Тема в разделе "PHP для новичков", создана пользователем Titos, 18 янв 2018.

Метки:
  1. Titos

    Titos Новичок

    С нами с:
    18 янв 2018
    Сообщения:
    4
    Симпатии:
    0
    Пишу валидацию есть вопросы! Хочется написать красиво, но не получается выводить ошибки. Давайте так я скину пример и ниже опишу в чём суть.

    Вот кусок кода:

    PHP:
    1. class UserController
    2. {
    3.     /**
    4.      * Action для страницы "Регистрация"
    5.      */
    6.     public function actionRegister()
    7.     {
    8.         // Переменные для формы
    9.         $login = false;
    10.         $email = false;
    11.         $password = false;
    12.         $result = false;
    13.  
    14.         // Обработка формы
    15.         if (isset($_POST['submit'])) {
    16.             // Если форма отправлена
    17.             // Получаем данные из формы
    18.             $login = $_POST['login'];
    19.             $email = $_POST['email'];
    20.             $password = $_POST['password'];
    21.  
    22.             // Флаг ошибок
    23.             $errors = false;
    24.  
    25.             // Валидация полей
    26.             if (!User::checkName($login)) {
    27.                 $errors[] = 'Имя не должно быть короче 2-х символов';
    28.             }
    29.             if (!User::checkEmail($email)) {
    30.                 $errors[] = 'Неправильный email';
    31.             }
    32.             if (!User::checkPassword($password)) {
    33.                 $errors[] = 'Пароль не должен быть короче 6-ти символов';
    34.             }
    35.             if (User::checkEmailExists($email)) {
    36.                 $errors[] = 'Такой email уже используется';
    37.             }
    38.  
    39.             if ($errors == false) {
    40.  
    41.                 //генерируем соль
    42.                 $salt = User::generateCode(5);
    43.                
    44.                 //получает хеш-сумму пароля и соли
    45.                 $password = md5($password.$salt);
    46.                
    47.                 // Если ошибок нет
    48.                 // Регистрируем пользователя
    49.                 User::register($login, $email, $password, $salt);
    50.  
    51.                 header("Location: /");
    52.             }
    53.         }
    54.  
    55.         // Подключаем вид
    56.         require_once(VIEW . '/user/register.php');
    57.         return true;
    58.     }
    59. }
    После нажатия кнопки формы данные проходят валидацию. Если какое либо поле не проходит проверку то в массив $errors = false; попадает значение ну допустим это $errors[] = 'Имя не должно быть короче 2-х символов';

    Данная функция которая проверяет длину строки находится в моделе User и имеет вид:

    PHP:
    1.     /**
    2.      * Проверяет имя: не меньше, чем 2 символа
    3.      */
    4.     public static function checkName($login)
    5.     {
    6.         if ($login >= 2) {
    7.             return true;
    8.         }
    9.         return false;
    10.     }
    Я хочу проверять не только длину строки но и скажем чтобы были только латинские буквы и кроме этого отсечь все цифры подчёркивания и прочее.

    Я хочу чтобы моя функция была не в одну строку, должна выводить предупреждения чтобы логин состоял из латинских символов и был не короче 2-х символов.

    По сути функция должна иметь такой вид:

    PHP:
    1. public static function checkName($login)
    2.     {
    3.       if(!preg_match("/^[a-zA-Z]{1,20}$/"), $login){
    4.             $errors[] = 'Логин должен быть из латинских символов и не более 20 символов';
    5.     }elseif(!$login >= 2){
    6.            $errors[] = 'Логин не должен быть короче 2-х символов';
    7.     }else{
    8.    return true;
    9. }
    10. }
    Когда я писал красиво имелось введу вот это(то что находится в экшене):

    PHP:
    1. f (!User::checkName($login)) {
    2.                 $errors[] = 'Имя не должно быть короче 2-х символов';
    3.             }
    Тут с выводом ошибок проблем нет.

    Хочется чтобы валидация логина была одной функцией, но у меня не получается из модели передать ошибки в массив $errors[] который находится в контроллере =) UserController

    Вот что делать кинуть этот код в контроллер? Ну будет же некрасиво... Да и данные должны же обрабатываться в моделе. Подскажите как быть?

    Я не знаю. Буду рад любому дельному совету.
     
  2. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    1. Логин емейл пароль. Пароль ладно, а логин и емейл зачем разделять? Почта должна быть и так уникальна - вот тебе и логин. А дальше уже можно юзеру дать возможность дополнительно выбрать себе уникальный юзернейм.
    2. Пароль хочу сам себе назначать. Не твоё это дело какие мне пароли нравятся. Хочу единичку ткнуть и ок нажать. Дай мне!
    3. Не храни мою единичку в открытом виде! Используй функции хэширования паролей и храни хэш пароля а не его значение. Ну пожалуйста!
    4. Соль при этом можешь не хранить, так как нормальная функция хэширования пароля и так умеет соль. Ты ей строки, а она тебе подсоленные хэши. Удобно же!
     
    artoodetoo и mahmuzar нравится это.
  3. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    В слаке вон вообще паролей нет, написал почту - получил ссылку для входа. Идеально же.
     
  4. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Html5 тоже может валидировать поля, в атрибутах можно длину тип хоть регуляркой проверять чтобы не гонять лишний раз сервер.
     
  5. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    @keren валидация на сервере при этом не отменяется.
     
  6. Titos

    Titos Новичок

    С нами с:
    18 янв 2018
    Сообщения:
    4
    Симпатии:
    0
    4 ответа и ни одного дельного совета. Я же не прошу сделать за меня! Я не знаю за что взяться! Этот проект - велосипед. Сам я продвинуться не могу. Так что давайте без флуда. Я старался для вас всё расписать имейте совесть!
     
  7. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    @Titos мой список из четырёх пунктов видел? Тебе из них как минимум научиться не хранить пароль в открытом виде.
     
  8. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    А давайте без "давайте", у вас тема как называется?
    Если у вас проблема:
    То наверное вам нужно почитать про функцию include
     
  9. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.752
    Симпатии:
    1.322
    Адрес:
    Лень
    PHP:
    1. // Обработка формы
    2.         if (isset($_POST['submit'])) {
    3.             // Если форма отправлена
    4.             // Получаем данные из формы
    5.             $login = $_POST['login'];
    6.             $email = $_POST['email'];
    7.             $password = $_POST['password'];
    vs
    PHP:
    1. if ( $_SERVER['REQUEST_METHOD'] === 'POST' )
    2. {
    3.    $args = [
    4.      'name' => [
    5.        'filter' => FILTER_VALIDATE_REGEXP,
    6.        'options' => [
    7.          'regexp' => '/^[A-Za-z0-9_-]{3,25}$/'
    8.        ]
    9.      ],
    10.      'email' => FILTER_VALIDATE_EMAIL,
    11.      'password' => FILTER_DEFAULT
    12.    ];
    13.  
    14.    $error = [];
    15.  
    16.    $inputs = filter_input_array ( INPUT_POST, $args );
    PHP:
    1.  // Флаг ошибок
    2.             $errors = false;
    Объявляем переменную с булевым значением, а используем ее как контейнер с массивами данных. Ошибка с типами.

    не нужна

    password_hash ( $pass, PASSWORD_DEFAULT );
    password_verify
    --- Добавлено ---
    Porno5 тоже может иметь всех, в трусах можно длину измерить и регулярно гонять лишний раз своего лысого.
     
  10. voral

    voral Активный пользователь

    С нами с:
    30 ноя 2017
    Сообщения:
    646
    Симпатии:
    104
    Хацкерам плевать что умеет HTML5 они будут долбить сайт не используя браузер
     
  11. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    Передай в функцию ссылку на массив $errors, и будет тебе счастье
     
  12. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Приведи пример пожалуйста, не уверен что я тебя понял.
     
  13. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.752
    Симпатии:
    1.322
    Адрес:
    Лень
    функция имя( $парам1, &$еррор )
     
    keren нравится это.
  14. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    PHP:
    1. function f(array &$errors) {
    2.       $errors[] = "Пользователь идиот";
    3. }
    4. $errors = [];
    5. for ($i = 0; $i < 10; $i++) {
    6.      f($errors);
    7. }
    8. var_export($errors);
     
    keren нравится это.
  15. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Ключевой момент "чтобы не гонять лишний раз на сервер". Валидация на стороне клиента - ни в коем случае не мера защиты. Это не более, чем мера добавления удобства для пользователя и снижения количества "ложных" запросов. Снижения, а не сведения к 0. Все эти валидации, при желании, обходятся без малейшего напряга прям в браузере.
     
  16. Titos

    Titos Новичок

    С нами с:
    18 янв 2018
    Сообщения:
    4
    Симпатии:
    0
    Видел. Я честно говоря части не понял. Не удалось Вам донести суть =). В общем с завтрашнего дня буду штудировать.
     
    #16 Titos, 19 янв 2018
    Последнее редактирование: 19 янв 2018
  17. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    Там как раз только суть и есть. Или ты из тех кому готовый год надо на блюдечке?
     
  18. AlNick

    AlNick Активный пользователь

    С нами с:
    19 авг 2017
    Сообщения:
    64
    Симпатии:
    3
    Насчёт длины пароля не согласен. Но все проверки данных, которые можно делать на стороне клиента, нужно там делать. В Вашем примере
    это длина логина и пароля. А остальные проверки уже на сервере. А хэшировать конечно нужно
     
  19. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    Проверки на стороне клиента могут быть любые, но они носят исключительно декоративный характер.

    p.s. а пароля вообще быть не должно. Сделайте авторизацию через соц.сети-гуглы, ну или спросите мыло что бы прислать на него одноразовую ссылку на вход. Ну и логин, да, ничего не бесит больше чем логин. Есть почта, что вам ещё надо то? ) Извиняюсь, накипело )
     
    Titos нравится это.
  20. AlNick

    AlNick Активный пользователь

    С нами с:
    19 авг 2017
    Сообщения:
    64
    Симпатии:
    3
    Большое спасибо Вам, что Вы решили за меня, как мне делать авторизацию
     
  21. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    И тогда, если ты не залогинен в почте/гугле/соцсетях, тебе придется вбивать логин и пароль там.
    Мне больше нравятся логины. Почт у меня много, а логинов нет. И логин короче почты. Изначально на проекте был вход только по логину. У части народа бомбило от того, что нет входа по почте. Переделка на вход по почте вызвала бы бомбеж у тех, кому удобнее с логином. В итоге сейчас можно входить и так и так, указываешь в поле либо логин, либо почту, а сервак сам разберется. Имхо - лучшее решение.
    --- Добавлено ---
    Да что ты вообще понимаешь в жизни и криптоустойчивости, мальчик? Не понимаешь ничего в кибербезопасности - не лезь, а делай то, что говорят профи:
    [​IMG]
    --- Добавлено ---
    Тот случай, когда ты вбиваешь люто сложный пароль на учетку, под которой крутится некоторое бабло, а эта дрянь просит тебя его УПРОСТИТЬ и не дает зарегаться.

    Вот правда, в сбере, в отделе разработок реально работают люди, которые думают, что хэш-функции не все равно?
     
    artoodetoo, askanim и MouseZver нравится это.
  22. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.752
    Симпатии:
    1.322
    Адрес:
    Лень
    У тебя зарядка на мобике заканчивается, покорми люлюку
     
    askanim и mahmuzar нравится это.
  23. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Уже давно :) Скрин вчера сделан.
     
  24. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Вот как раз понимают что не надо шутить с баблом и совать туда как попало кодируемые многобайтные иероглифы.
     
  25. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Еще один знаток принципов работы хэш-функций подъехал?
    Расскажешь мне, как многобайтные иероглифы могут помешать при правильном хранении пароля? Дам тысячу рублей, если раскроешь мне уязвимости, которые так можно эксплуатировать при том же password_hash(). Если таковых не раскроется, ты мне должен будешь тысячу. По рукам?