Skip to content

Instantly share code, notes, and snippets.

@Angels-group
Forked from zmts/tokens.md
Created May 24, 2018 07:42
Show Gist options
  • Save Angels-group/70ea0f9a3e4f17d8602ba17c96185dbd to your computer and use it in GitHub Desktop.
Save Angels-group/70ea0f9a3e4f17d8602ba17c96185dbd to your computer and use it in GitHub Desktop.

Revisions

  1. @zmts zmts revised this gist May 19, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # Token-Based Authentication(JWT)
    # Про токены, JSON Web Tokens (JWT), аутентификацию и авторизацию. Token-Based Authentication(JWT)

    ## Preconditions:
    В данной заметке рассматривается работа JWT с __симметичным__ алгоритмом шифрования (HS256/HS384/HS512)
  2. @zmts zmts revised this gist May 1, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -122,7 +122,7 @@ __Проблема:__ Поскольку __refresh token__ продлевает
    - дополнительно шифровать токены (в nodejs например crypt >> aes-256)

    ### Пример имплементации:
    __Front-end:__ https://github.com/zmts/vuejs-boilerplate/blob/master/src/services/http.init.js
    __Front-end:__ https://github.com/zmts/beauty-vuejs-boilerplate/blob/master/src/services/http.init.js

    __Back-end:__ https://github.com/zmts/supra-api-nodejs/tree/master/actions/auth

  3. @zmts zmts revised this gist May 1, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -78,7 +78,7 @@ __Если рассматривать возможность аутентифи
    ```
    При создании рефрештокена я дополнительно его шифрую. __П__ - паранойя.
    https://github.com/zmts/supra-api-nodejs/blob/master/services/auth/cryptoEncryptService.js
    И использую эго __Initialization Vector__ в качестве __refreshTokenId__. Но можно прекрасно обойтись и без дополнительного шифрования и без JSONB, просто создав для рефреш токенов отдельную таблицу __one-to-many__. Возможно стоит так сделать и мне.
    И использую время создания (__timestamp__) в качестве __refreshTokenId__. Но можно прекрасно обойтись и без дополнительного шифрования и без JSONB, просто создав для рефреш токенов отдельную таблицу __one-to-many__. Возможно стоит так сделать и мне.

    __Схема(без учета доп. шифрования):__
    1. Клиент проверяет перед запросом не истекло ли время жизни __access token'на__
  4. @zmts zmts revised this gist Apr 15, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -99,7 +99,7 @@ __Схема(без учета доп. шифрования):__

    Как дополнительная мера можно вообще заблокировать данного юзера при попытке залогинится более чем на 10ти устройствах. С возможностью разблокировки только через email. Но в этом случае нам необходимо будет во время каждого рефреша проверять список токенов на наличие мертвых(не валидных).

    ## Ключевой момент
    ## Ключевой момент:
    В момент рефреша то есть обновления __access token'a__ обновляются __ОБА__ токена. Но как же __refresh token__ может сам себя обновить, он ведь создается только после успешной аунтефикации ? __refresh token__ в момент рефреша сравнивает себя с тем __refresh token'ом__ который лежит в БД и вслучае успеха, а также если у него не истек срок, система рефрешит токены. __Внимание__ при обновлении __refresh token'a__ продливается также и его срок жизни.

    Возникает вопрос зачем __refresh token'y__ срок жизни, если он обновляется каждый раз при обновлении __access token'a__ ? Это сделано на случай если юзер будет в офлайне более 60 дней, тогда прийдется заново вбить логин/пароль.
  5. @zmts zmts revised this gist Apr 15, 2018. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -99,7 +99,8 @@ __Схема(без учета доп. шифрования):__

    Как дополнительная мера можно вообще заблокировать данного юзера при попытке залогинится более чем на 10ти устройствах. С возможностью разблокировки только через email. Но в этом случае нам необходимо будет во время каждого рефреша проверять список токенов на наличие мертвых(не валидных).

    __Ключевой момент__ что в момент рефреша то есть обновления __access token'a__ обновляются __ОБА__ токена. Но как же __refresh token__ может сам себя обновить, он ведь создается только после успешной аунтефикации ? __refresh token__ в момент рефреша сравнивает себя с тем __refresh token'ом__ который лежит в БД и вслучае успеха, а также если у него не истек срок, система рефрешит токены. __Внимание__ при обновлении __refresh token__ продливается также и его срок жизни.
    ## Ключевой момент
    В момент рефреша то есть обновления __access token'a__ обновляются __ОБА__ токена. Но как же __refresh token__ может сам себя обновить, он ведь создается только после успешной аунтефикации ? __refresh token__ в момент рефреша сравнивает себя с тем __refresh token'ом__ который лежит в БД и вслучае успеха, а также если у него не истек срок, система рефрешит токены. __Внимание__ при обновлении __refresh token'a__ продливается также и его срок жизни.

    Возникает вопрос зачем __refresh token'y__ срок жизни, если он обновляется каждый раз при обновлении __access token'a__ ? Это сделано на случай если юзер будет в офлайне более 60 дней, тогда прийдется заново вбить логин/пароль.

  6. @zmts zmts revised this gist Apr 15, 2018. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions tokens.md
    Original file line number Diff line number Diff line change
    @@ -51,10 +51,6 @@ __Поскольку токены это не зашифрованная инф
    3. Клиент сохраняет токены и время смерти __access token'а__, используя __access token__ для последующей авторизации запросов
    4. Перед каждым запросом клиент предварительно проверяет время жизни __access token'а__ (из `expires_in`)и если оно истекло использует __refresh token__ чтобы обновить __ОБА__ токена и продолжает использовать новый __access token__

    __Ключевой момент__ что в момент рефреша то есть обновления __access token'a__ обновляются __ОБА__ токена. Но как же __refresh token__ может сам себя обновить, он ведь создается только после успешной аунтефикации ? __refresh token__ в момент рефреша сравнивает себя с тем __refresh token'ом__ который лежит в БД и вслучае успеха, а также если у него не истек срок, система рефрешит токены. __Внимание__ при обновлении __refresh token__ продливается также и его срок жизни.

    Возникает вопрос зачем __refresh token'y__ срок жизни, если он обновляется каждый раз при обновлении __access token'a__ ? Это сделано на случай если юзер будет в офлайне более 60 дней, тогда прийдется заново вбить логин/пароль.

    ## Схема рефреша токенов (api/auth/refresh-tokens):
    1. Клиент проверяет перед запросом не истекло ли время жизни __access token'на__
    2. Если истекло клиент отправляет на `auth/refresh-token` URL __refresh token__
    @@ -103,6 +99,10 @@ __Схема(без учета доп. шифрования):__

    Как дополнительная мера можно вообще заблокировать данного юзера при попытке залогинится более чем на 10ти устройствах. С возможностью разблокировки только через email. Но в этом случае нам необходимо будет во время каждого рефреша проверять список токенов на наличие мертвых(не валидных).

    __Ключевой момент__ что в момент рефреша то есть обновления __access token'a__ обновляются __ОБА__ токена. Но как же __refresh token__ может сам себя обновить, он ведь создается только после успешной аунтефикации ? __refresh token__ в момент рефреша сравнивает себя с тем __refresh token'ом__ который лежит в БД и вслучае успеха, а также если у него не истек срок, система рефрешит токены. __Внимание__ при обновлении __refresh token__ продливается также и его срок жизни.

    Возникает вопрос зачем __refresh token'y__ срок жизни, если он обновляется каждый раз при обновлении __access token'a__ ? Это сделано на случай если юзер будет в офлайне более 60 дней, тогда прийдется заново вбить логин/пароль.

    ## В случае кражи(обоих токенов):
    1. Хакер воспользовался __access token'ом__
    2. Закончилось время жизни __access token'на__
  7. @zmts zmts revised this gist Apr 15, 2018. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions tokens.md
    Original file line number Diff line number Diff line change
    @@ -40,7 +40,7 @@ __refresh token__ - выдается сервером по результам у

    __Поскольку токены это не зашифрованная информация крайне не рекомендуется хранить в них такую информацию как пароли__

    ## Схема создания/использования токенов:
    ## Схема создания/использования токенов (api/auth/login):
    1. Пользователь логинится в приложении, передавая логин/пароль на сервер
    2. Сервер проверят подлинность логина/пароля, в случае удачи генерирует и отправляет клиенту два токена(__access, refresh__) и время смерти __access token'а__ (`expires_in` поле, в __unix timestamp__). Также в __payload__ __refresh token'a__ добавляется __user_id__
    ```
    @@ -55,7 +55,7 @@ __Ключевой момент__ что в момент рефреша то е

    Возникает вопрос зачем __refresh token'y__ срок жизни, если он обновляется каждый раз при обновлении __access token'a__ ? Это сделано на случай если юзер будет в офлайне более 60 дней, тогда прийдется заново вбить логин/пароль.

    ## Схема рефреша токенов:
    ## Схема рефреша токенов (api/auth/refresh-tokens):
    1. Клиент проверяет перед запросом не истекло ли время жизни __access token'на__
    2. Если истекло клиент отправляет на `auth/refresh-token` URL __refresh token__
    3. Сервер берет __user_id__ из __payload'a__ __refresh token'a__ по нему ищет в БД запись данного юзера и достает из него __refresh token__
    @@ -71,7 +71,7 @@ __С такой схемой юзер сможет быть залогинен

    __Если рассматривать возможность аутентификации на более чем одном девайсе/браузере:__ необходимо хранить весь список валидных рефреш токенов юзера. Если юзер авторизовался более чем на ±10ти устройствах(что есть весьма подозрительно), автоматически инвалидоровать все рефреш токены кроме текущего и отправлять email с security уведомлением. Как вариант список токенов можно хранить в jsonb(если используется PostgreSQL).

    ## Схема рефреша токенов (мульти сессии):
    ## Схема рефреша токенов (мульти сессии, api/auth/refresh-tokens):
    Для использования возможности аутентификации на более чем одном девайсе необходимо хранить все рефреш токены по каждому юзеру. Я этот список храню в записи юзера в виде JSONB.
    ```
    -------------------------------------------------------------------------------------------------
  8. @zmts zmts revised this gist Apr 15, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -81,7 +81,7 @@ __Если рассматривать возможность аутентифи
    -------------------------------------------------------------------------------------------------
    ```
    При создании рефрештокена я дополнительно его шифрую. __П__ - паранойя.
    https://github.com/zmts/supra-api-nodejs/blob/master/services/auth/cryptoEncryptServiceSync.js
    https://github.com/zmts/supra-api-nodejs/blob/master/services/auth/cryptoEncryptService.js
    И использую эго __Initialization Vector__ в качестве __refreshTokenId__. Но можно прекрасно обойтись и без дополнительного шифрования и без JSONB, просто создав для рефреш токенов отдельную таблицу __one-to-many__. Возможно стоит так сделать и мне.

    __Схема(без учета доп. шифрования):__
  9. @zmts zmts revised this gist Apr 15, 2018. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions tokens.md
    Original file line number Diff line number Diff line change
    @@ -89,7 +89,7 @@ __Схема(без учета доп. шифрования):__
    2. Если истекло клиент отправляет на `auth/refresh-token` URL __refresh token__
    3. Сервер берет __user_id__ из __payload'a__ __refresh token'a__ по нему ищет в БД запись данного юзера и достает из него __refresh token__
    4. Сравнивает __refresh token__ клиента с __refresh token'ом__ найденным в БД
    5. Проверяет валидность и срок действия __refresh token'а__
    5. Проверяет валидность и срок действия __refresh token'а__ (но если токен не валиден удаляет его сразу)
    6. В случае успеха сервер:
    1. __Удаляет старый рефреш токен__
    2. Проверяет количество уже существующих решфреш токенов.
    @@ -99,7 +99,9 @@ __Схема(без учета доп. шифрования):__
    6. Отправляет оба токена и новый `expires_in` __access token'а__ клиенту
    7. Клиент повторяет запрос к API c новым __access token'ом__

    Таким образом если юзер залогинился на пяти устройствах, рефреш токены будут постоянно обновлятся и все счастливы. Но если с аккаунтом юзера начнут производить подозрительные действия(попытаются залогинится более чем на 10ти устройствах) система сбросит все сессии(рефреш токены) кроме последней. Либо как дополнительная мера, вообще заблокировать данного юзера. С возможностью разблокировки только через email.
    Таким образом если юзер залогинился на пяти устройствах, рефреш токены будут постоянно обновлятся и все счастливы. Но если с аккаунтом юзера начнут производить подозрительные действия(попытаются залогинится более чем на 10ти устройствах) система сбросит все сессии(рефреш токены) кроме последней.

    Как дополнительная мера можно вообще заблокировать данного юзера при попытке залогинится более чем на 10ти устройствах. С возможностью разблокировки только через email. Но в этом случае нам необходимо будет во время каждого рефреша проверять список токенов на наличие мертвых(не валидных).

    ## В случае кражи(обоих токенов):
    1. Хакер воспользовался __access token'ом__
  10. @zmts zmts revised this gist Apr 15, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -99,7 +99,7 @@ __Схема(без учета доп. шифрования):__
    6. Отправляет оба токена и новый `expires_in` __access token'а__ клиенту
    7. Клиент повторяет запрос к API c новым __access token'ом__

    Таким образом если юзер залогинился на пяти устройствах, рефреш токены будут постоянно обновлятся и все счастливы. Но если с аккаунтом юзера начнут производить подозрительные действия(попытатся залогинится более чем на 10ти устройствах) система сбросит все сессии(рефреш токены) кроме последней. В дополнение можно выслать юзеру на мыло уведомление.
    Таким образом если юзер залогинился на пяти устройствах, рефреш токены будут постоянно обновлятся и все счастливы. Но если с аккаунтом юзера начнут производить подозрительные действия(попытаются залогинится более чем на 10ти устройствах) система сбросит все сессии(рефреш токены) кроме последней. Либо как дополнительная мера, вообще заблокировать данного юзера. С возможностью разблокировки только через email.

    ## В случае кражи(обоих токенов):
    1. Хакер воспользовался __access token'ом__
  11. @zmts zmts revised this gist Apr 15, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -97,7 +97,7 @@ __Схема(без учета доп. шифрования):__
    4. Если их меньше 10 просто создает и записывает новый в БД.
    5. Создает новый __access token__
    6. Отправляет оба токена и новый `expires_in` __access token'а__ клиенту
    7. Клиент повторяет запрос к API c новым __access token'ом__.
    7. Клиент повторяет запрос к API c новым __access token'ом__

    Таким образом если юзер залогинился на пяти устройствах, рефреш токены будут постоянно обновлятся и все счастливы. Но если с аккаунтом юзера начнут производить подозрительные действия(попытатся залогинится более чем на 10ти устройствах) система сбросит все сессии(рефреш токены) кроме последней. В дополнение можно выслать юзеру на мыло уведомление.

  12. @zmts zmts revised this gist Apr 15, 2018. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -97,7 +97,8 @@ __Схема(без учета доп. шифрования):__
    4. Если их меньше 10 просто создает и записывает новый в БД.
    5. Создает новый __access token__
    6. Отправляет оба токена и новый `expires_in` __access token'а__ клиенту
    7. Клиент повторяет запрос к API c новым __access token'ом__
    7. Клиент повторяет запрос к API c новым __access token'ом__.

    Таким образом если юзер залогинился на пяти устройствах, рефреш токены будут постоянно обновлятся и все счастливы. Но если с аккаунтом юзера начнут производить подозрительные действия(попытатся залогинится более чем на 10ти устройствах) система сбросит все сессии(рефреш токены) кроме последней. В дополнение можно выслать юзеру на мыло уведомление.

    ## В случае кражи(обоих токенов):
  13. @zmts zmts revised this gist Apr 15, 2018. 1 changed file with 6 additions and 3 deletions.
    9 changes: 6 additions & 3 deletions tokens.md
    Original file line number Diff line number Diff line change
    @@ -92,10 +92,13 @@ __Схема(без учета доп. шифрования):__
    5. Проверяет валидность и срок действия __refresh token'а__
    6. В случае успеха сервер:
    1. __Удаляет старый рефреш токен__
    2. Создает и записывает новый __refresh token__ в БД
    2. Создает новый __access token__
    3. Отправляет оба токена и новый `expires_in` __access token'а__ клиенту
    2. Проверяет количество уже существующих решфреш токенов.
    3. Если их больше 10, удаляет все токены, создает новый и запиывает его в БД.
    4. Если их меньше 10 просто создает и записывает новый в БД.
    5. Создает новый __access token__
    6. Отправляет оба токена и новый `expires_in` __access token'а__ клиенту
    7. Клиент повторяет запрос к API c новым __access token'ом__
    Таким образом если юзер залогинился на пяти устройствах, рефреш токены будут постоянно обновлятся и все счастливы. Но если с аккаунтом юзера начнут производить подозрительные действия(попытатся залогинится более чем на 10ти устройствах) система сбросит все сессии(рефреш токены) кроме последней. В дополнение можно выслать юзеру на мыло уведомление.

    ## В случае кражи(обоих токенов):
    1. Хакер воспользовался __access token'ом__
  14. @zmts zmts revised this gist Apr 15, 2018. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions tokens.md
    Original file line number Diff line number Diff line change
    @@ -116,6 +116,7 @@ __Проблема:__ Поскольку __refresh token__ продлевает

    ### Пример имплементации:
    __Front-end:__ https://github.com/zmts/vuejs-boilerplate/blob/master/src/services/http.init.js

    __Back-end:__ https://github.com/zmts/supra-api-nodejs/tree/master/actions/auth

    ### Чтиво:
  15. @zmts zmts revised this gist Apr 15, 2018. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -115,7 +115,8 @@ __Проблема:__ Поскольку __refresh token__ продлевает
    - дополнительно шифровать токены (в nodejs например crypt >> aes-256)

    ### Пример имплементации:
    https://github.com/zmts/vuejs-boilerplate/blob/master/src/services/http.init.js
    __Front-end:__ https://github.com/zmts/vuejs-boilerplate/blob/master/src/services/http.init.js
    __Back-end:__ https://github.com/zmts/supra-api-nodejs/tree/master/actions/auth

    ### Чтиво:
    - https://tools.ietf.org/html/rfc6749
  16. @zmts zmts revised this gist Apr 15, 2018. 1 changed file with 28 additions and 2 deletions.
    30 changes: 28 additions & 2 deletions tokens.md
    Original file line number Diff line number Diff line change
    @@ -57,12 +57,12 @@ __Ключевой момент__ что в момент рефреша то е

    ## Схема рефреша токенов:
    1. Клиент проверяет перед запросом не истекло ли время жизни __access token'на__
    2. И если истекло клиент отправляет на `auth/refresh-token` URL __refresh token__
    2. Если истекло клиент отправляет на `auth/refresh-token` URL __refresh token__
    3. Сервер берет __user_id__ из __payload'a__ __refresh token'a__ по нему ищет в БД запись данного юзера и достает из него __refresh token__
    4. Сравнивает __refresh token__ клиента с __refresh token'ом__ найденным в БД
    5. Проверяет валидность и срок действия __refresh token'а__
    6. В случае успеха сервер:
    1. Пересоздает и записывает __refresh token__ в БД
    1. Создает и записывает __refresh token__ в БД
    2. Создает новый __access token__
    3. Отправляет оба токена и новый `expires_in` __access token'а__ клиенту
    7. Клиент повторяет запрос к API c новым __access token'ом__
    @@ -71,6 +71,32 @@ __С такой схемой юзер сможет быть залогинен

    __Если рассматривать возможность аутентификации на более чем одном девайсе/браузере:__ необходимо хранить весь список валидных рефреш токенов юзера. Если юзер авторизовался более чем на ±10ти устройствах(что есть весьма подозрительно), автоматически инвалидоровать все рефреш токены кроме текущего и отправлять email с security уведомлением. Как вариант список токенов можно хранить в jsonb(если используется PostgreSQL).

    ## Схема рефреша токенов (мульти сессии):
    Для использования возможности аутентификации на более чем одном девайсе необходимо хранить все рефреш токены по каждому юзеру. Я этот список храню в записи юзера в виде JSONB.
    ```
    -------------------------------------------------------------------------------------------------
    | id | username | refreshTokensMap
    -------------------------------------------------------------------------------------------------
    | 1 | alex | { refreshTokenId1: 'refreshTokenBody1', refreshTokenId2: 'refreshTokenBody2'}
    -------------------------------------------------------------------------------------------------
    ```
    При создании рефрештокена я дополнительно его шифрую. __П__ - паранойя.
    https://github.com/zmts/supra-api-nodejs/blob/master/services/auth/cryptoEncryptServiceSync.js
    И использую эго __Initialization Vector__ в качестве __refreshTokenId__. Но можно прекрасно обойтись и без дополнительного шифрования и без JSONB, просто создав для рефреш токенов отдельную таблицу __one-to-many__. Возможно стоит так сделать и мне.

    __Схема(без учета доп. шифрования):__
    1. Клиент проверяет перед запросом не истекло ли время жизни __access token'на__
    2. Если истекло клиент отправляет на `auth/refresh-token` URL __refresh token__
    3. Сервер берет __user_id__ из __payload'a__ __refresh token'a__ по нему ищет в БД запись данного юзера и достает из него __refresh token__
    4. Сравнивает __refresh token__ клиента с __refresh token'ом__ найденным в БД
    5. Проверяет валидность и срок действия __refresh token'а__
    6. В случае успеха сервер:
    1. __Удаляет старый рефреш токен__
    2. Создает и записывает новый __refresh token__ в БД
    2. Создает новый __access token__
    3. Отправляет оба токена и новый `expires_in` __access token'а__ клиенту
    7. Клиент повторяет запрос к API c новым __access token'ом__

    ## В случае кражи(обоих токенов):
    1. Хакер воспользовался __access token'ом__
    2. Закончилось время жизни __access token'на__
  17. @zmts zmts revised this gist Mar 31, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -28,7 +28,7 @@ __JSON Web Token (JWT)__ — содержит три блока, разделе
    { «alg»: «HS256», «typ»: «JWT» }.{ «iss»: «auth.myservice.com», «aud»: «myservice.com», «exp»: «1435937883», «userName»: «John Smith», «userRole»: «Admin» }.S9Zs/8/uEGGTVVtLggFTizCsMtwOJnRhjaQ2BMUQhcY
    ```

    __Токены__ предоставляют собой средство __авторизации__ для каждого запроса от клиента к серверу. Токены(и соотвественно сигнатура токена) генерируются на сервере основываясь на секретном ключе(который хранится на сервере) и __payload'e__. Токен в итоге хранится на клиенте и используется при необходимости __авторизации__ како-го либо запроса. Такое решение отлично подходит при разаработке SPA.
    __Токены__ предоставляют собой средство __авторизации__ для каждого запроса от клиента к серверу. Токены(и соотвественно сигнатура токена) генерируются на сервере основываясь на секретном ключе(который хранится на сервере) и __payload'e__. Токен в итоге хранится на клиенте и используется при необходимости __авторизации__ како-го либо запроса. Такое решение отлично подходит при разработке SPA.

    При попытке хакером подменить данные в __header'ре__ или __payload'е__, токен cтанет не валидным, поскольку сигнатура не будет соответствовать изначальным значениям. А возможность сгенерировать новую сигнатуру у хакера отсутствует, поскольку секретный ключ для зашифровки лежит на сервере.

  18. @zmts zmts revised this gist Mar 25, 2018. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions tokens.md
    Original file line number Diff line number Diff line change
    @@ -88,6 +88,9 @@ __Проблема:__ Поскольку __refresh token__ продлевает
    - хранить список валидных IP, deviceID, fingerprint браузера, генерить рандомный randomUserID
    - дополнительно шифровать токены (в nodejs например crypt >> aes-256)

    ### Пример имплементации:
    https://github.com/zmts/vuejs-boilerplate/blob/master/src/services/http.init.js

    ### Чтиво:
    - https://tools.ietf.org/html/rfc6749
    - https://jwt.io/introduction/
  19. @zmts zmts revised this gist Mar 3, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -69,7 +69,7 @@ __Ключевой момент__ что в момент рефреша то е

    __С такой схемой юзер сможет быть залогинен только на одном устройстве.__ Тоесть в любом случае при смене устройства ему придется логинится заново.

    __Если рассматривать возможность аутентификации на более чем одном девайсе/браузере:__ необходимо хранить весь список валидных рефреш токенов юзера. Если юзер авторизовался более чем на ±10ти устройствах(что есть весьма подозрительно), автоматически инвалидоровать все рефреш токены кроме текущего и отправлять email с security уведомлением. Как вариант список токенов можно хранит в jsonb(если используется PostgreSQL).
    __Если рассматривать возможность аутентификации на более чем одном девайсе/браузере:__ необходимо хранить весь список валидных рефреш токенов юзера. Если юзер авторизовался более чем на ±10ти устройствах(что есть весьма подозрительно), автоматически инвалидоровать все рефреш токены кроме текущего и отправлять email с security уведомлением. Как вариант список токенов можно хранить в jsonb(если используется PostgreSQL).

    ## В случае кражи(обоих токенов):
    1. Хакер воспользовался __access token'ом__
  20. @zmts zmts revised this gist Mar 3, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@

    ## Основы:

    __Аутентификация(authentication, от греч. αὐθεντικός [authentikos] – реальный, подлинный; от αὐθέντης [authentes] – автор)__ - это процесс проверки учётных данных пользователя (логин/пароль). Проверка подлинности пользователя путём сравнения введённого им пароля с паролем, сохранённым в базе данных пользователей.
    __Аутентификация(authentication, от греч. αὐθεντικός [authentikos] – реальный, подлинный; от αὐθέντης [authentes] – автор)__ - это процесс проверки учётных данных пользователя (логин/пароль). Проверка подлинности пользователя путём сравнения введённого им логина/пароля с логином/паролем, сохранённым в базе данных пользователей.

    __Авторизация(authorization — разрешение, уполномочивание)__ - это проверка прав пользователя на доступ к определенным ресурсам.

  21. @zmts zmts revised this gist Mar 3, 2018. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions tokens.md
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@

    ## Основы:

    __Аутентификация(authentication, от греч. αὐθεντικός [authentikos] – реальный, подлинный; от αὐθέντης [authentes] – автор)__ - это процесс проверки учётных данных пользователя (логин/пароль). Проверка подлинности пользователя путём сравнения введённого им пароля с паролем, сохранённым в базе данных пользователей;
    __Аутентификация(authentication, от греч. αὐθεντικός [authentikos] – реальный, подлинный; от αὐθέντης [authentes] – автор)__ - это процесс проверки учётных данных пользователя (логин/пароль). Проверка подлинности пользователя путём сравнения введённого им пароля с паролем, сохранённым в базе данных пользователей.

    __Авторизация(authorization — разрешение, уполномочивание)__ - это проверка прав пользователя на доступ к определенным ресурсам.

    @@ -69,7 +69,7 @@ __Ключевой момент__ что в момент рефреша то е

    __С такой схемой юзер сможет быть залогинен только на одном устройстве.__ Тоесть в любом случае при смене устройства ему придется логинится заново.

    __Если рассматривать возможность авторизации на более чем одном девайсе/браузере:__ необходимо хранить весь список валидных рефреш токенов юзера. Если юзер авторизовался более чем на ±10ти устройствах(что есть весьма подозрительно), автоматически инвалидоровать все рефреш токены кроме текущего и отправлять email с security уведомлением. Как вариант список токенов можно хранит в jsonb(если используется PostgreSQL).
    __Если рассматривать возможность аутентификации на более чем одном девайсе/браузере:__ необходимо хранить весь список валидных рефреш токенов юзера. Если юзер авторизовался более чем на ±10ти устройствах(что есть весьма подозрительно), автоматически инвалидоровать все рефреш токены кроме текущего и отправлять email с security уведомлением. Как вариант список токенов можно хранит в jsonb(если используется PostgreSQL).

    ## В случае кражи(обоих токенов):
    1. Хакер воспользовался __access token'ом__
  22. @zmts zmts revised this gist Mar 3, 2018. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions tokens.md
    Original file line number Diff line number Diff line change
    @@ -55,8 +55,6 @@ __Ключевой момент__ что в момент рефреша то е

    Возникает вопрос зачем __refresh token'y__ срок жизни, если он обновляется каждый раз при обновлении __access token'a__ ? Это сделано на случай если юзер будет в офлайне более 60 дней, тогда прийдется заново вбить логин/пароль.

    С такой схемой юзер сможет быть залогинен только на одном устройстве. Тоесть в любом случае при смене устройства ему придется логинится заново.

    ## Схема рефреша токенов:
    1. Клиент проверяет перед запросом не истекло ли время жизни __access token'на__
    2. И если истекло клиент отправляет на `auth/refresh-token` URL __refresh token__
    @@ -69,6 +67,10 @@ __Ключевой момент__ что в момент рефреша то е
    3. Отправляет оба токена и новый `expires_in` __access token'а__ клиенту
    7. Клиент повторяет запрос к API c новым __access token'ом__

    __С такой схемой юзер сможет быть залогинен только на одном устройстве.__ Тоесть в любом случае при смене устройства ему придется логинится заново.

    __Если рассматривать возможность авторизации на более чем одном девайсе/браузере:__ необходимо хранить весь список валидных рефреш токенов юзера. Если юзер авторизовался более чем на ±10ти устройствах(что есть весьма подозрительно), автоматически инвалидоровать все рефреш токены кроме текущего и отправлять email с security уведомлением. Как вариант список токенов можно хранит в jsonb(если используется PostgreSQL).

    ## В случае кражи(обоих токенов):
    1. Хакер воспользовался __access token'ом__
    2. Закончилось время жизни __access token'на__
  23. Sasha Zmts revised this gist Aug 27, 2017. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions tokens.md
    Original file line number Diff line number Diff line change
    @@ -48,8 +48,8 @@ __Поскольку токены это не зашифрованная инф
    "refreshToken": "...",
    "expires_in": 1502305985425
    ```
    3. Приложение сохраняет токены и время смерти __access token'а__, используя __access token__ для последующей авторизации запросов
    4. Перед каждым запросом клиент предварительно проверяет время жизни __access token'а__ (из `expires_in`)и если оно истекло клиент использует __refresh token__ чтобы обновить __ОБА__ токена и продолжить использовать новый __access token__
    3. Клиент сохраняет токены и время смерти __access token'а__, используя __access token__ для последующей авторизации запросов
    4. Перед каждым запросом клиент предварительно проверяет время жизни __access token'а__ (из `expires_in`)и если оно истекло использует __refresh token__ чтобы обновить __ОБА__ токена и продолжает использовать новый __access token__

    __Ключевой момент__ что в момент рефреша то есть обновления __access token'a__ обновляются __ОБА__ токена. Но как же __refresh token__ может сам себя обновить, он ведь создается только после успешной аунтефикации ? __refresh token__ в момент рефреша сравнивает себя с тем __refresh token'ом__ который лежит в БД и вслучае успеха, а также если у него не истек срок, система рефрешит токены. __Внимание__ при обновлении __refresh token__ продливается также и его срок жизни.

  24. Sasha Zmts revised this gist Aug 27, 2017. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions tokens.md
    Original file line number Diff line number Diff line change
    @@ -95,8 +95,6 @@ __Проблема:__ Поскольку __refresh token__ продлевает
    - https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/
    - https://habrahabr.ru/company/dataart/blog/262817/
    - https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens


    - Заметка базируется на: https://habrahabr.ru/company/Voximplant/blog/323160/
    - https://www.youtube.com/watch?v=Ngh3KZcGNaU
    - https://www.youtube.com/playlist?list=PLvTBThJr861y60LQrUGpJNPu3Nt2EeQsP
  25. Sasha Zmts revised this gist Aug 27, 2017. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions tokens.md
    Original file line number Diff line number Diff line change
    @@ -96,6 +96,7 @@ __Проблема:__ Поскольку __refresh token__ продлевает
    - https://habrahabr.ru/company/dataart/blog/262817/
    - https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens


    - Заметка базируется на: https://habrahabr.ru/company/Voximplant/blog/323160/
    - https://www.youtube.com/watch?v=Ngh3KZcGNaU
    - https://www.youtube.com/playlist?list=PLvTBThJr861y60LQrUGpJNPu3Nt2EeQsP
  26. Sasha Zmts revised this gist Aug 27, 2017. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -94,8 +94,10 @@ __Проблема:__ Поскольку __refresh token__ продлевает
    - https://auth0.com/blog/ten-things-you-should-know-about-tokens-and-cookies/
    - https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/
    - https://habrahabr.ru/company/dataart/blog/262817/
    - https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens

    - Заметка базируется на: https://habrahabr.ru/company/Voximplant/blog/323160/
    - https://www.youtube.com/watch?v=Ngh3KZcGNaU
    - https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens
    - https://www.youtube.com/playlist?list=PLvTBThJr861y60LQrUGpJNPu3Nt2EeQsP


  27. Sasha Zmts revised this gist Aug 26, 2017. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions tokens.md
    Original file line number Diff line number Diff line change
    @@ -60,8 +60,8 @@ __Ключевой момент__ что в момент рефреша то е
    ## Схема рефреша токенов:
    1. Клиент проверяет перед запросом не истекло ли время жизни __access token'на__
    2. И если истекло клиент отправляет на `auth/refresh-token` URL __refresh token__
    3. Сервер смотрит в __payload__ __refresh token'a__ берет __user_id__, ищет по БД данного юзера и достает из него __refresh token__
    4. Сравнивает __refresh token__ от клиента с __refresh token'ом__ найденным в БД
    3. Сервер берет __user_id__ из __payload'a__ __refresh token'a__ по нему ищет в БД запись данного юзера и достает из него __refresh token__
    4. Сравнивает __refresh token__ клиента с __refresh token'ом__ найденным в БД
    5. Проверяет валидность и срок действия __refresh token'а__
    6. В случае успеха сервер:
    1. Пересоздает и записывает __refresh token__ в БД
  28. Sasha Zmts revised this gist Aug 9, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -60,7 +60,7 @@ __Ключевой момент__ что в момент рефреша то е
    ## Схема рефреша токенов:
    1. Клиент проверяет перед запросом не истекло ли время жизни __access token'на__
    2. И если истекло клиент отправляет на `auth/refresh-token` URL __refresh token__
    3. Сервер смотрит в __payload__ __refresh token'a__ берет __user_id__, ищет по БД данного юзера и достает из записи найденного юзера __refresh token__
    3. Сервер смотрит в __payload__ __refresh token'a__ берет __user_id__, ищет по БД данного юзера и достает из него __refresh token__
    4. Сравнивает __refresh token__ от клиента с __refresh token'ом__ найденным в БД
    5. Проверяет валидность и срок действия __refresh token'а__
    6. В случае успеха сервер:
  29. Sasha Zmts revised this gist Aug 9, 2017. 1 changed file with 10 additions and 4 deletions.
    14 changes: 10 additions & 4 deletions tokens.md
    Original file line number Diff line number Diff line change
    @@ -40,9 +40,14 @@ __refresh token__ - выдается сервером по результам у

    __Поскольку токены это не зашифрованная информация крайне не рекомендуется хранить в них такую информацию как пароли__

    ## Схема использования токенов:
    ## Схема создания/использования токенов:
    1. Пользователь логинится в приложении, передавая логин/пароль на сервер
    2. Сервер проверят подлинность логина/пароля, в случае удачи генерирует и отправляет клиенту два токена(__access, refresh__) и время смерти __access token'а__ (`expires_in` поле, в __unix timestamp__)
    2. Сервер проверят подлинность логина/пароля, в случае удачи генерирует и отправляет клиенту два токена(__access, refresh__) и время смерти __access token'а__ (`expires_in` поле, в __unix timestamp__). Также в __payload__ __refresh token'a__ добавляется __user_id__
    ```
    "accessToken": "...",
    "refreshToken": "...",
    "expires_in": 1502305985425
    ```
    3. Приложение сохраняет токены и время смерти __access token'а__, используя __access token__ для последующей авторизации запросов
    4. Перед каждым запросом клиент предварительно проверяет время жизни __access token'а__ (из `expires_in`)и если оно истекло клиент использует __refresh token__ чтобы обновить __ОБА__ токена и продолжить использовать новый __access token__

    @@ -55,8 +60,9 @@ __Ключевой момент__ что в момент рефреша то е
    ## Схема рефреша токенов:
    1. Клиент проверяет перед запросом не истекло ли время жизни __access token'на__
    2. И если истекло клиент отправляет на `auth/refresh-token` URL __refresh token__
    3. Сервер сравнивает __refresh token__ от клиента с __refresh token'ом__ лежащим в БД
    4. Сервер проверяет валидность и срок действия __refresh token'а__
    3. Сервер смотрит в __payload__ __refresh token'a__ берет __user_id__, ищет по БД данного юзера и достает из записи найденного юзера __refresh token__
    4. Сравнивает __refresh token__ от клиента с __refresh token'ом__ найденным в БД
    5. Проверяет валидность и срок действия __refresh token'а__
    6. В случае успеха сервер:
    1. Пересоздает и записывает __refresh token__ в БД
    2. Создает новый __access token__
  30. Sasha Zmts revised this gist Aug 9, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion tokens.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    # Token-Based Authentication(JWT)

    ## Предварительные условия:
    ## Preconditions:
    В данной заметке рассматривается работа JWT с __симметичным__ алгоритмом шифрования (HS256/HS384/HS512)

    ## Основы: