• Ближайшее меньшее число?

    abler98
    @abler98
    PHP, Java, Android
    <?php
    
    $value = 20;
    $array = [0, 10, 15, 8, 25, 35, 45, 100];
    
    if (!in_array($value, $array)) {
        $value = max(array_filter($array, function ($v) use ($value) {
            return $v < $value;
        }));
    }
    
    echo $value; // 15
    Ответ написан
  • Как правильно написать авторизацию/аутентификацию?

    dasha_programmist
    @dasha_programmist
    ex Software Engineer at Reddit TS/React/GraphQL/Go
    Есть два варианта хранения данных об авторизованном пользователе:
    1) В куки (так по умолчанию используется в асп.нет): необходимые данные (claims) шифруются machineKey и отдаются пользователю в http-only куках, таким образом при каждом запросе на сервер они присылаются, расшифровываются и далее можно проверить в необходимых местах.
    плюсы: полностью stateless, нет надобности обращаться к БД
    минусы: при необходимости "выбить" сессию со стороны сервера нужно поднимать более сложную логику и хранить флаги в промежуточном хранилище (проверять что если для такого-то пользователя требуется завершить, то такие действия, иначе другие);
    2) Ключ сессии: после успешной аутентификации авторизуем пользователя и claims храним на сервере в быстрой памяти или БД (key-value), где ключ - ключ сессии, значение - любые данные.
    плюсы: есть полный контроль состоянием авторизации (как и возможность завершить сессию со стороны сервера, так и сменить пользователю роль(или другие параметры) "на лету")
    минусы: организация доп. прослойки - кэша или хранение в БД (медленно), при перезапуске/падении сервиса сессии клиентам потребуется перелогиниться.

    1
    1.1 В куки писать или ключ сессии или шифрованные данные о пользователе, сессия - абстрактное понятие (это пара: ключ и данные), ключ должен быть защищенным, т.е. трудным к копированию (хотя бы зрительно трудно запомнить), уникальным (чтобы не возникло коллизий: двум разным пользователям выдался один и тот же ключ, т.е. это не должна быть хэш-функция от логина-пароля или IP или чего-то неуникального).
    1.2 В асп.нет существуют атрибуты авторизации (в которых можно расставлять проверки на требование таковой, роль, конкретный пользователь), в общем смысле логика такова: поступил запрос на сервер, далее нужно посмотреть к какому ресурсу идёт обращение (защищенному или свободному), если ресурс защищен, то проверить куки (ключ сессии или шифрованные данные), расшифровать/получить данные о сессии из кэша и предпринять решение: пускаем или не пускаем (отдаём 401/403 или отдаем 200/404/...).
    1.3 Завести на сервере (в кэше или БД) словарь , при алгоритме проверки сессии добавить условие проверки на наличие записи в словаре.
    1.4 С нескольких - словаря не нужно.

    2
    2.1 Даже если пользователь входит через ВК всё равно нужно отдавать свои ключи сессий/шифрованные данные, а вот внутри данных уже хранить access_token от вк-шной сессии, так очень маленькая вероятность, что токен ВК утечет, а если утек ключ сессии, то действия будут ограничены только функционалом сайта.
    2.2 После расшифровки куки или данных по ключу сессии делать доп запрос на сервер ВК с токеном, который сохранился при аутентификации (access_token), запрос простой, например получить имя пользователя, если ВК выдал что токен просрочен или ошибку, то сессию закрывать или куки с данными обнулять.
    Ответ написан
  • Фильтрация данных?

    FanatPHP
    @FanatPHP
    Чебуратор тега PHP
    Ты как и все пхпшники путаешь валидацию и форматирование данных.

    Форматирование обязательно, по правилам той среды, в которую ты отправляешь данные.
    У тебя это
    - при использовании переменной в запросе делать это через подготовленные выражения
    - при выводе переменной в браузер обрабатывать через htmlspecialchars

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

    Про кэширование вообще забудь, это ты наслушался дуремаров-теоретиков, которые сайт у мамки на ноутбуке видели два раза в жизни.
    Ответ написан
  • Фильтрация данных?

    delphinpro
    @delphinpro
    frontend developer
    пароль htmlspecialchars для перестраховки

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

    минимальную фильтрацию где это необходимо

    верное направление мысли.

    Необходимо в двух местах:
    1. запись базу
    2. вывод на страницу

    Чтобы защититься от sql-injection при записи, используйте подготовленные запросы.
    Чтобы не сломать верстку при выводе данных — используйте htmlspecialchars при рендере страницы. А лучше возьмите шаблонизатор. Они все по умолчанию эскейпят вывод.

    разрешить в логин и имя только a-zа-яё0-9


    Это уже не фильтрация, а валидация данных, к безопасности особого отношения не имеет и выполняется в других местах приложения.
    Простой пример. Пользователь отправил форму.
    Вы первым делом сделаете проверку всех полей на допустимые значения, на заполненность и т.д., и если что вернете посетителя обратно на форму с указанием ошибки. Данные здесь не изменяются.
    Если все в порядке, вы будете писать эти данные в базу. Как я уже написал, используя подготовленный запрос. Опять же, ничего менять в них не требуется.
    Потом, вы будете эту информацию где-то выводить на странице. Вот здесь уже, перед выводом, вы прогоните все через htmlspecialchars, возможно какие-то еще корректировки сделаете.

    Но, опять же вы пишете про универсальную фильтрацию на все случаи. Так не бывает.
    Если вы ожидаете во входных данных исключительно текст, то можно, например, смело резать все теги перед записью в базу. А если вы получаете их из визуального редактора, с разметкой, то резать теги уже не нужно.
    Ответ написан
  • Что лучше использовать для хранения уникальных за сутки ip адресов?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Redis вполне подходит для задачи.

    К примеру, для каждого ip формировать ключ вида дата:ip. Например SET "20210205:192.168.1.5" "" — для каждого ip создавать ключ с пустой строкой.

    После полуночи IP начнут сохраняться с новой датой, а PHP скрипт по крону разберёт предыдущие сутки KEYS "20210205:*" и сохранит собранные IP в БД.

    Ещё лучше каждые сутки держать как хэш, где имя это дата, поля ip, и значения счетчики хитов с этого ip. Делать каждый раз HINCRBY "дата" "ip" 1 См. HINCRBY

    P.S. ip, если там только IPv4, это 4 байта, можно хранить как целые числа, а не строки – компактнее.
    Ответ написан
  • Array_chunk + последний эелемент массива дублируется в первый следующего?

    GogElf
    @GogElf
    Хокаге
    Мой вариант
    $array = [
    	...
    ];
    
    $chunks = [];
    while($array){
    	$current = array_splice($array, 0, 4);
    	if(isset($old))
    		array_unshift($current, $old);
    	$old = end($current);
    	$chunks[] = $current;
    };
    
    print_r($chunks);
    Ответ написан
  • Array_chunk + последний эелемент массива дублируется в первый следующего?

    Compolomus
    @Compolomus Куратор тега PHP
    Комполом-быдлокодер
    Что то такое родилось
    $array = [
        '127.0.0.1',
        '127.0.0.2',
        '127.0.0.3',
        '127.0.0.4',
        '127.0.0.5',
        '127.0.0.6',
        '127.0.0.7',
        '127.0.0.8',
        '127.0.0.9',
    ];
    
    $result = []; // результат
    
    $len = 4; // длинна первого массива (менять для экспериментов)
    
    $c = ceil(count($array) / $len) - 1; // количество итераций
    
    $result[] = array_slice($array, 0, $len); // первый срез
    
    $offset = $len - 1; // смещение для первой итерации
    
    for (++$len, $j = 0, $i = 0; $i < $c; $i++, $offset += $len - 1, $j += $len) {
        $result[] = array_slice($array, $offset, $len);
    }
    
    echo '<pre>' . print_r($result, true) . '</pre>';
    Ответ написан
  • Array_chunk + последний эелемент массива дублируется в первый следующего?

    nokimaro
    @nokimaro
    Меня невозможно остановить, если я смогу начать.
    <?php
    $array = [
      '127.0.0.1',
      '127.0.0.2',
      '127.0.0.3',
      '127.0.0.4',
      '127.0.0.5',
      '127.0.0.6',
      '127.0.0.7',
      '127.0.0.8',
      '127.0.0.9',
    ];
    
    $chunks = array_chunk($array, 4);
    
    foreach($chunks as $key => $vals)
    {
        $next_chunk_key = $key+1;
        if(isset($chunks[$next_chunk_key]))
        {
            //добавляем в начало след. чанка последний элемент текущего чанка
            array_unshift($chunks[$next_chunk_key], end($vals));
        }
    }
    
    print_r($chunks);
    Ответ написан