• Как правильно проверять возраст на php?

    iiiBird
    @iiiBird
    Пока ты спишь - твой конкурент совершенствуется
    <?php
    $birthDate = '20.02.2010';
    if (time() < strtotime('+18 years', strtotime($birthDate))) {
        echo 'меньше 18';
    } else {
        echo 'больше 18';
    }
    Ответ написан
    1 комментарий
  • Как сопоставить параметры в CRM при интеграции через входящий вебхук?

    gromdron
    @gromdron Куратор тега Битрикс24
    Работаю с Bitrix24
    Добавляется пустой лид, как сделать, чтобы данные добавлялись в соответствующие поля?


    В документации (https://dev.1c-bitrix.ru/rest_help/crm/leads/crm_l...) сказано что метод crm.lead.add принимает 2 параметра: fields и params.
    Вы НЕ передаете эти параметры, но передаете параметры NAME и PHONE.

    Отсюда можно сказать что ваш запрос должен выглядеть так:

    bitrix.site.ru/rest/107/dklsaubnbfsdfsfanh3a/crm.lead.add.json?fields[NAME]=111111&fields[PHONE]=1111111111111

    Однако я не рекомендую передавать параметры напрямую в query string, а использовать вместо этого payload часть вашего запроса.

    Как ее использовать?
    1. Выполняете не GET, а POST запросы
    2. В Content-type заголовке передаете application/json
    3. В payload-части передаете json.
    Ответ написан
    Комментировать
  • Как разделить на равные части динамическое количество детей для flex?

    @DivineDraft
    Ответ написан
    Комментировать
  • Как написать регулярное выражение для роутов?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    Просмотр назад нужен, если по-простому исправлять:
    regex = /(?<=:)([a-z0-9_]*)/gi;

    Ещё можно через цикл сделать. А так вообще зависит от условий. Если структура всегда такая, ровно 4 секции, ровно две из них с двоеточием, и меняются только a-z, то решение я написал выше, иначе нужно будет усложнять регулярку и/или сопутствующий код.
    Ответ написан
    2 комментария
  • Можно ли аргумент функции (array) принудительно привести к объекту?

    profesor08
    @profesor08 Куратор тега PHP
    А зачем эти сложности? Тебе хочется пользоваться объектами, так в чем проблема не использовать для этого массивы, чтоб потом не думать, как эти массивы переводить в объекты. И молиться, что ты не упустил какое-то там свойство, которое тебе выстрелит неизвестно когда.

    <?php
    
    class Project {
      public int $id;
      public string $name;
      
      public function __construct(int $id, string $name) {
        $this->id = $id;
        $this->name = $name;
      }
    }
    
    class ProjectWithLogo extends Project {
      public string $logo;
      
      public function __construct(Project $project, string $logo) {
        $this->id = $project->id;
        $this->name = $project->name;
        $this->logo = $logo;
      }
    }
    
    function mapperProject(Project $project): ProjectWithLogo {
      return new ProjectWithLogo($project, "logo-path");
    }
    
    var_dump(mapperProject(new Project(123, "Pet Project")));
    Ответ написан
    6 комментариев
  • Как принять данные при POST запросе через php://input?

    @zkrvndm
    Софт для автоматизации
    При отправке FormData поток php://input автоматом очищается во время формирования $_POST, такое поведение конечно же можно отключить, но это кастрирует ваш сервер и массив $_POST просто перестанет формироваться при получении данных. Вы бы лучше написали зачем именно вам это надо, а там видно будет, вдруг вы изобретаете велосипед.
    Ответ написан
    Комментировать
  • Какой подход использовать для валидации данных?

    E1ON
    @E1ON
    Programming, Gamedev, VR
    Я бы использовал Симфони валидатор.
    Как уже написали выше - валидировать ValueObjectы.
    Либо если ты разрабатываешь архитектуру для своего приложения, то можно имплементировать валидацию реквестов в контроллере, тем же симфони валидатором.
    Ответ написан
    Комментировать
  • Какой подход использовать для валидации данных?

    Валидация, масштабируемость и юзабилити, это как бы совсем разное.

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

    На бэке при этом должна присутствовать всё та же валидация, чтобы не было возможности сохранить невалидным данные прямыми запросами.

    Для гибкости - контроллер валидирует только соответствие структуры запроса (ругается что не хватает значений, или ожидали данные в одном формате, а пришли в другом). Сами данные в процессе обработки оборачивать в самовалидируемые ValueObjectы, которые при создании будут уже проверять данные на соответствие более специфичным требованиям.

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

    И т.д. и т.п.
    Ответ написан
    5 комментариев
  • Как правильно организовать архитектуру авторизации/аутентификации?

    inoise
    @inoise
    Solution Architect, AWS Certified, Serverless
    1. Да и пофиг. Не прислали токен (по любой причине) - мы тебя не знаем, сходи за талончиком адрес вот
    2. Если мы говорим про фронт то по-хорошему надо, но на практике не так играет роль потому что поведение 401 unauthorized все-равно реализовывать (токен могут просто отозвать же)
    Ответ написан
    1 комментарий
  • Как правильно обработать получение access токена в interceptors на axios?

    @Bart0725
    Мое решение, которое я использую при авторизации к КК

    import _ from 'lodash';
    const mainFetch = axios.create();
    
    export const issueToken = () => {
        return new Promise((resolve, reject) => {
            return keycloak.updateToken(30000).success((refreshed) => {
                if (refreshed) {
                    resolve(keycloak.token);
                    sessionStorage.setItem("kctoken", `${keycloak.token}`);
                } else {
                    console.log('not refreshed ' + new Date());
                }
            }).error(() => {
                reject();
                keycloakLogout();
            });
        });
    }
    
    mainFetch.interceptors.request.use((config) => {
        let originalRequest = config;
        if (keycloak.isTokenExpired(30000)) {
            return issueToken().then((token) => {
                _.set(originalRequest, 'headers.Authorization', `Bearer ${token}`);
                return Promise.resolve(originalRequest);
            });
        } else {
            _.set(config, 'headers.Authorization', `Bearer ${sessionStorage.getItem("kctoken")}`);
        }
        return config;
    }, (err) => {
        return Promise.reject(err);
    });


    Работает оно так, при запросе обращаемся к КК специальным методом isTokenExpired в моем случае за 30 секунд до протухания, если время истекает запрашиваем новый и возвращаем конфиг с новым токеном, если нет - берем токен из сессии
    Ответ написан
    Комментировать
  • Почему cookies не сетятся через setcookie на php?

    karabanov
    @karabanov
    Системный администратор
    Убери точку, чтобы стало просто site.ru
    Можно установить cookie из поддомена на домене, но нельзя установить cookie из домена на поддомене - браузер отвергнет такую cookie.
    Ответ написан
    2 комментария
  • Что делать с ошибкой линтера и какие лучше зависимости включать для useEffect?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Довольно спорная тема. На гитхабе было обсуждение, где Ден увещевал всех забыть про "componentDidMount" и мыслить зависимостями - раз уж компонент по сути отражение текущего стейта.
    В твоём случае ничего не меняется, потому нужно просто добавить эти значения в депсы и не заморачиваться. Диспатч всегда постоянный, так что включай тоже.
    Собственно, проблема может возникнуть, если интересует только значение на момент маунта и ты сознательно не хочешь эффектить при изменении. Тогда можно просто сделать, например, const firstValue = useRef(propValue).current; ,тогда в firstValue у тебя будет только первое значение, которое можно передать в useEffect. Это тоже костыль, но более явный код, чем еслинт-дизабл.
    Ответ написан
    Комментировать
  • Как настроить взаимодействие FE (localhost) с BE (remote server) с withCredentials?

    Обычно авторизация возвращается токен (можно например в виде JWT) который передается в фронтенд, фронтенд проверяет токен проверкой подписи или серверсайдным запросом и проставляет куку.
    Ответ написан
    7 комментариев
  • Как установить cookie с помощью php при работе с rest api?

    nokimaro
    @nokimaro
    Меня невозможно остановить, если я смогу начать.
    Нужно выставить "withCredentials" в клиенте

    const app = axios.create({
        baseURL,
        withCredentials: true
    })
    Ответ написан
    1 комментарий
  • Как реализовать авторизацию/аутентификацию с помощью access/refresh tokens с использованием JWT?

    nowm
    @nowm
    3. Оба ли эти токены будут являться JWT?

    JWT — это строка, сформированная в соответствие с RFC7519. Если формат правильный, это JWT, если нет — это не JWT. Если вы распечатаете JWT-токен на бумаге и используете её как кулёк для семечек, эти токены не перестанут быть JWT-токенами. То есть, область применения никак не влияет на то, JWT это или нет — только формат самого токена.

    ---

    Суть Access- и Refresh-токенов в том, что у вас может быть 10 разных серверов, один из которых используется для авторизации. На сервере авторизации вы генерируете токены и сообщаете их клиенту, каким-то способом, безопасность и удобство которого вас устраивает. Кто-то в куках передаёт, кто-то прямыми ответами сервера. Остальные 9 серверов принимают запросы, в которых указаны Access-токены. Тут тоже можно разными способами это делать. Можно в GET-параметрах токен передавать, можно в куках, можно в теле запроса, можно использовать хэдер Authorization — опять же, это на ваше усмотрение, в зависимости от того, какой способ вам кажется более удобным или более безопасным. На этих 9 серверах есть открытые ключи авторизационного сервера либо они могут обратиться к авторизационному серверу за ними. Используя эти открытые ключи, они проверяют Access-токен на валиднось, и если всё хорошо, выполняют запрос, в котором был этот токен, вытаскивая из токена, например, идентификатор текущего пользователя и используя его дальше. Сами эти 9 серверов не занимаются генерацией токенов вообще. Они только проверяют их. Соответственно, им не требуется хранить в БД или в кэше конкретные токены, чтобы удостоверяться в легитимности запроса, им нужен только открытый ключ авторизационного сервера, закрытой частью которого он подписывает эти токены. Это упрощает на их стороне логику, и они могут сосредоточиться на своих узких задачах.

    Авторизационный сервер занимается только генерацией токенов. Именно он решает, что, например, Access-токен должен жить 3 минуты, а Refresh-токен — 30 дней. Он делает свои личные проверки любых данных, которые может достать (IP, UA, идентификатор сессии и так далее) — вы сами решаете и сами пишете логику того, какие проверки нужно делать и как. Если вы считаете, что в полнолуние нужно отказывать в генерации токена для браузера Firefox пользователям из Кении, именно так и программируйте систему, потому что за вас библиотека JWT автоматом такие проверки делать не будет — это не её назначение. Её назначение проверять и создавать JWT-токены из данных, которые вы ей даёте на входе. Среди этих данных могут быть идентификаторы пользователя, сессии и т.п., если вы сами захотели их туда засунуть.

    Когда вы запрашиваете новый Access-токен, передавая в параметрах Refresh-токен (опять же, передавать его можно разными способами в зависимости от ваших вкусов и того, как вы запрограммировали сервер), авторизационный сервер проверяет его валидность и принимает решение, выдавать новый токен или нет. Вполне можно построить систему так, чтобы Refresh-токен не приходилось хранить в БД на стороне сервера авторизации, потому что все нужные данные можно поместить прямо в payload токена — он всё равно подписывается, так что если клиент подменит там идентификатор пользователя, токен не пройдёт валидацию.

    Фишка с Access- и Refresh-токенами нужна для того, чтобы организовать распределённую работу нескольких серверов. Если вы генерируете токены на сервере, а потом на этом же сервере принимаете запросы, в которых используется Access-токен, вы делаете что-то неправильно, потому что в таких ситуациях городить подобную архитектуру не нужно, и передавать Refresh-токен вместе с Access-токеном API-серверу тоже не нужно, потому что генерация новых токенов — это не его забота.

    Немного выше я писал, что токены со стороны клиента можно передавать по-разному в зависимости от предпочтений: в куках, в GET-параметрах, в теле запроса или в хэдере Authorization. Хорошая практика — это когда вы передаёте их в хэдере Authorization и больше никак. Делаете запрос к API-серверу? В хэдер помещается Access-токен. Делаете запрос на продление токена к авторизационному серверу? В хэдер помещается Refresh-токен. Всё просто и однотипно.
    Ответ написан
    1 комментарий
  • Как обезопасить пароли при регистрации/авторизации?

    ThunderCat
    @ThunderCat Куратор тега PHP
    {PHP, MySql, HTML, JS, CSS} developer
    Отличный подход - заранее знать что твои данные в дырявых руках )
    Если код сольют, разницы никакой не будет, точнее password_hash() даже понадежнее будет.
    Если код не сольют, а допустим только бд вытащат, hash_hmac выглядит надежнее, но по сути не сильно далеко от первого варианта.

    На практике во первых задрачивать в псевдобезопасность абсолютно никакого смысла не имеет, ибо password_hash() достаточно надежен, и если уж очень хочется "понадежнее" - cost побольше и вперед, а во вторых плодить кастомные решения в обход специализированных функций это фуфуфу, кака, моветон и гемор всем кто будет это поддерживать.
    Ответ написан
    2 комментария
  • Как обезопасить пароли при регистрации/авторизации?

    Adamos
    @Adamos
    3. Использовать готовые решения из популярных фреймворков.
    Поскольку оба варианта 1 и 2 в теории более чем достаточны для любого обычного сайта, а вот на практике в самописной авторизации неуверенный программист может просто-напросто налажать.
    Ответ написан
    1 комментарий
  • Можно ли регистрировать название домена, если на западе есть аналогичный сервис в зоне .com?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Все завист как всегда - от денег :) Если "там" большая толстая контора с десятком прикормленных юристов - они могут его просто отсудить. А могут и не отсуживать - а купить. Есть множество вариантов.
    Если же "там" контора примерно равная по возможностям - варианты будут другими. Здесь не бывает однозначного ответа.
    Ответ написан
    2 комментария
  • Можно ли регистрировать название домена, если на западе есть аналогичный сервис в зоне .com?

    alexgp13
    @alexgp13
    Руководитель ИТ-проектов
    Кроме домена проверьте регистрацию товарного знака в РФ. Если что-то зарегистрировано - лучше не лезть.
    В целом, зарегистрировать то домен можно, права на имя на другие страны не распространяются.
    Если компания решит выйти на российский рынок, то есть варианты. Если бизнес схожий - могут предложить объединиться. Но могут и попытаться отсудить. Как повезет.
    Ответ написан
    Комментировать