• Как реализовать авторизацию/аутентификацию с помощью 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 комментарий
  • Как сделать 2 div (один над другим) одинаковыми по высоте?

    Madgod
    @Madgod
    Помещаешь оба div в блок. Блоку даешь такие стили.
    .block {
      display: grid;
      grid-template-rows: repeat(2, 1fr);
    }


    https://codepen.io/danil-klimov/pen/VwmEPrq
    Ответ написан
    Комментировать
  • Как сделать 2 div (один над другим) одинаковыми по высоте?

    @MEDIOFF
    Python Developer
    Запихнуть их в один контейнер и задать обоим высоту в 50%, либо так же через flex, просто вместо высоты flex-basis.
    Ответ написан
    Комментировать
  • Почему Docker Tomcat запускается, но с ошибкой 404?

    @q2digger
    никого не трогаю, починяю примус
    Хорошая привычка, прежде чем разворачивать какой то контейнер, поискать что пишет его автор, хотя бы на докерхабе.
    Итак, идем https://hub.docker.com/_/tomcat
    И находим там фразу:
    Note: as of docker-library/tomcat#181, the upstream-provided (example) webapps are not enabled by default, per upstream's security recommendations, but are still available under the webapps.dist folder within the image to make them easier to re-enable.
    Ответ написан
    Комментировать
  • Почему при деплое war на удаленный Tomcat ошибка: Cannot invoke Tomcat manager: Connection reset by peer: socket write error?

    xez
    @xez Куратор тега Java
    TL Junior Roo
    Проблема с доступом к менеджеру.
    Рецепт тут:
    https://stackoverflow.com/questions/36703856/acces...
    Ответ написан
    Комментировать
  • Сервлеты, многопоточность, как устроено?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Java
    Седой и строгий
    При запуске Tomcat создаст пул потоков и экземпляр сервлета. При поступлении запросов методы сервлета будут запускаться на потоках из пула. Сервлет не уничтожается до окончания работы сервера.

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

    С кэшированием надо крайне аккуратно, так как это как раз та область, в которой можно нарваться на проблемы многопоточности.
    Ответ написан
  • Почему при создании контекста спринга через GenericXmlApplicationContext не работает @Transactional?

    @TonyJa
    Spring, когда видит @Transactional создает прокси по интерфейсу AssetsRepository, поэтому он и не находит JpaAssetsRepository. Попробуйте делать лукап по интерфейсу
    AssetsRepository rep3 = appCtx.getBean(AssetsRepository .class)
    Ответ написан
    Комментировать