Comments 20
За все время работы с этой библой, я так и не понял пользу от нее. Выпилил ее и не жалею!
Не через все, а те которые необходимы. и это один раз было проделано. Проблем вообще никаких.
JWT придуман для того, чтобы каждый раз не обращаться к базе, иначе там смысла мало. Вы сохраняете user_id, role и ещё что нибудь туда и при получении токена (если подпись верна), можете смело использовать значения, не ходя за ними в базу.

Т.е. вот так делать не стоит…
new JwtStrategy(params, (payload, done) =>
  UserModel.findOne({where: {id: payload.userId}})
Согласен. Но вопросы начинают возникать когда эти данные меняются. Например пользователь администратор уволился с работы и я должен убрать у него роль admin.
Для этого вам нужно просто отозвать его токен. При следующей авторизации, новый токен будет создан с новой ролью.

jwt живет только на протяжении сессии, если ваш админ уволился то вы убираете роль, и при следующем логине в его jwt роль админ у него не будет.

Это вопрос инвалидации JWT в принципе. И решается кучей разных способов. Можно делать blacklist, можно отзывать secret, можно делать шардирование secret и отзывать один из 10 к примеру (чтобы 90% не вылетали) и тп.
Вобщем-то, с одной стороны все ясно. Нужно пользоваться access+refresh токенами. Первые ограничены по времени действия и поэтому при следующем запросе access токена опять будут актуальные данные. Однако такой путь на мой взгляд приносит усложнение в фроненд. Во всяком случае пока для iOS и Android не появится широко распространенная и всеми используемая библиотека которая будет выполнять эту работу за кадром.

Что касается идеи с отзывом токенов. Ее как мне кажется целесообразно использовать в связке с access+refresh токенами для «мгновенного» отзыва до следующей ротации access токенов. Иначе мы получим базу отозванных токенов запросы к которой будут сравнимы по затратам с запросами профиля пользователя.

Но все это как-то начинает усложнять схему особенно в отсутствии некоторого фреймверка который бы все это делал за кадром, и который должен поддерживаться на всех оcновных клиентах (iOS, Android, web) и на сервере (желательно тоже не на одном)
Иначе мы получим базу отозванных токенов запросы к которой будут сравнимы по затратам с запросами профиля пользователя

В примере с уволенным админом достаточно держать в ENV переменной что-то вроде BLACKLIST_JWT через запятую. Вы не каждый день увольняете людей, поэтому так можно. Современный процессы continuous deployment позволяют менять env в течении пары минут.

Или ещё проще — делать blacklist на уровне балансера (nginx без проблем через map и if). Или в redis держать backlist jwt. Все очень сильно зависит от задач и проекта. Очень часто не нужно ничего навороченного.

apapacy промазал, для вас ответ.
В примере с уволенным админом достаточно держать в ENV переменной что-то вроде BLACKLIST_JWT через запятую. Вы не каждый день увольняете людей, поэтому так можно. Современный процессы continuous deployment позволяют менять env в течении пары минут.

Эмм… это вы сейчас серьезно предлагаете делать нового приложения каждый раз когда надо сделать токен не валидным? Или у нас разное понимание слова «deployment»?
Опечатался, delivery. Просто правка файла, git push и через минуту приложение обновилось.
Честно говоря — исправление опечатки не сильно помогло) Суть ведь не поменялась. Вы все еще пытаетесь решить хардкодом то, что должно решаться изменением данных. То есть — делаете вашу систему невозможной к использованию обычным пользователем. Да еще и используете в качестве хранилища — совершенно не подходящее место.
Можно, конечно, принять оговорку про разные проекты — но мне очень тяжко придумать где я хотел бы вешать на себя такой геморрой вместо того чтоб юзер становился заблокированным от одного нажатия на кнопку «уволить».
Я несколько раз повторил, что это зависит от проекта и задачи, привел несколько вариантов решения. а вы выбрали простейший и говорите, что он «не для пользователя». Вам нужно — пишите. А я ради события, которое раз в год происходит не буду писать код, который нужно поддерживать, тестировать и не сломать через пару лет. Каждый день — напишу, каждую неделю — напишу, а увольнения админа в вакуме — нет.
Время от времени в разного рода статьях читаю про то, что `UserModel.find({id:...})` будет заметно влиять на производительность.

Но скажите, какую функцию выполняет приложение? Если один запрос с хорошим слючом по небольшой компактной таблице заметно влияет на производительность.
Обычно по производительности база данных это первый ограничивающий фактор с которым сталкивается приложение. Не совсем понимаю что такое хороший ключ и может ли быть таблица компактной если у меня несколько миллионов пользователей. И какое отношение имеет функция приложения к авторизации. Просто есть приложения где не нужна авторизация и есть приложение в котором нужна авторизация. И если авторизация нужна тогда нужен объект user. Откуда его брать это уже следующий вопрос. Можно из подписанного токена или из сессии. Можно лезть в основную базу данных. Можно для этого организовать отдельную базу данных или сервис.
Хороший ключ это уникальное короткое поле, выборка по которому происходит максимально эфективно.

Таблица с юзерскими авторизационными записями (если в нее не пихать весь профайл, конечно) компактна и там не больше одного чтения на запись получается — она влазит в буфер с запасом. Миллион таких записей это примерно гиг, а реальный ворксет вообще легко в ОЗУ помещается.

Это я все к тому, что вот этот пример с сессиями в базе встречается довольно часто рядом со словом «производительность», но на деле тут очень не много получается соптимизировать в принципе. А вот найти себе неочевидного гемора с размазыванием сейта по токенам можно найти очень легко.
Мне кажется более точного говорить не BASE, а Basic. Именно так это поле называется в HTTP заголовках.
Также сталкивались с подобной задачей:
по требованию разработчиков фронтенда добавить в 401 ответ объект с описанием ошибки (по умолчанию это строка «Unauthorized»)

Была найдена альтернатива failWithError: true из «коробки» passport.js (правда, не описанная в официальной документации), которая позволяет вернуть кастомное сообщение с ошибкой без реализации кастомного коллбека. Пример:

app.post('/auth',
  passport.authenticate('local', { failWithError: true }),
  function(req, res, next) {
    // Successful auth
    return res.send({ success: true, message: 'Logged in' })
  },
  function(err, req, res, next) {
    // Auth error
    return res.status(401).send({ success: false, message: err })
  }
)
Тоже читал это issue только не был уверен что это уже в релизе. Скорее всего перейду на этот вариант. Хотя стоп. Это же в каждый роут нужно будет добавить? Хотелось бы сделать это один раз
Only those users with full accounts are able to leave comments. Log in, please.