Skip to content

murash22/jwt-auth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

Запуск

Выполните docker-compose up для запуска с дефолтными параметрами

Пример .env файла

Пример .env файла с базовыми настройками уже лежит в корне проекта

Комментарии по решению

хранимые поля для refresh-token

В базе храню refresh_token. Поля:

  • uuid UUID PRIMARY KEY NOT NULL - уникальный идентификатор токена
  • user_id UUID NOT NULL, - владелец токена
  • value TEXT NOT NULL, - bcrypt хеш токена
  • ip_addr TEXT NOT NULL, - адрес с которого был сгенерирован
  • user_agent TEXT NOT NULL, - UserAgent при созданиии токена
  • expires_at TIMESTAMP NOT NULL, - время истечения токена
  • created_at TIMESTAMP NOT NULL DEFAULT NOW()

/auth/access

Генерирую пару токенов и возвращаю. При каждой генерации, сначала пытаюсь удалить по user_id старый refresh-token из бд и затем генерирую новый

/auth/refresh

refresh-token - случайная строка из 64 байт. Пользователю отдаю как base64(uuid.refresh-token) Для выполнения операции refresh требуется 2 токена (в прошлый раз сделали замечание, что обновлял только по refresh-token. На этот раз требуется еще и access-token). Порядок выполнения операции refresh:

  • Проверяю валидность access токена. Только подпись, не ttl (иначе какой вообще смысл от refresh-token если у него такое же время жизни - не совсем понимаю). Если валидная подпись, то иду дальше.
  • Проверяю валидность refresh-токена: декодирую из base64, достаю tokenUUID и по нему запаршиваю полный токен из бд. Если не нашелся, значит невалидный токен. Если нашелся, то смотрю TTL, совпадение bcrypt хешов, принадлежность одному и тому же владельцу (user_id из access_token и user_id из refresh-token из бд) => если не прошли проверки, возвращаю invalid token error. Дальше удаляю токен из бд по tokenUUID (по сути деавторизовываю). Сравниваю UserAgent и если не совпадают, то возвращаю invalid token err сразу. Дальше генерирую новые токены и сохраняю refresh. Сравниваю старый и новый ip и если не совпадают, то отправляю POST запрос на webhook. Возвращаю новую пару токенов.

Webhook - он 1 для всего приложения. Задается при запуске в .env файле.

/auth/logout

При деавторизации пользователя, удаляю refresh-token из базы. Но access_token будет действовать еще некоторое время, ибо по условию нельзя хранить никакой инфы по access_token (вести список инвалидированных или еще что-то) Поэтому просто задал поменьше TTL у access_token.

/auth/me

Проверяю токен на валидность и возвращаю user_id из токена. В токен payload как-раз таки храню только userId. Можно было бы еще хранить IpAddr, UserAgent, чтобы уменьшить количество запросов в бд, но решил, что это лишняя инфа для payload

swagger ui

Будет доступен по http://localhost:8080/swagger/index.html. В description у каждого роута есть пример заполнения поля, нужно только подставить сгенерированные токены.

В description у роута написал, но продублирую еще и сюда: При тестировании через swagger-ui в браузере, роут /auth/refresh будет работать немного некорректно. Когда обновляется токен, сервер посылает SetCookie refresh-token и браузер сразу подставляет это значение в куки. Из-за этого Если нажать 2+ раз на /auth/refresh с одними и теми же access и refresh токенами, то это будет работать, хотя на самом деле, токены обновляются.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors