Я создаю RESTful API, который использует токены JWT для аутентификации пользователя (выпущенные login
конечной точкой и отправленные во всех заголовках впоследствии), и токены необходимо обновить через фиксированное время (вызывая renew
конечную точку, которая возвращает обновленный токен ).
Возможно, что сеанс API пользователя становится недействительным до истечения срока действия токена, поэтому все мои конечные точки начинаются с проверки того, что: 1) токен все еще действителен и 2) сеанс пользователя все еще действителен. Нет возможности напрямую аннулировать токен, потому что клиенты хранят его локально.
Поэтому все мои конечные точки должны сигнализировать моим клиентам о двух возможных условиях: 1) что пришло время обновить токен или 2) что сеанс стал недействительным, и им больше не разрешен доступ к системе. Я могу придумать две альтернативы для моих конечных точек, чтобы сигнализировать своим клиентам, когда происходит одно из двух условий (предположим, что клиенты могут быть адаптированы к любому варианту):
- Верните код http 401 (неавторизованный), если сеанс стал недействительным, или верните код 412 (предварительное условие не выполнено), когда токен истек, и пришло время вызвать
renew
конечную точку, которая вернет код 200 (ok). - Возврат 401 для сигнализации о том, что либо сеанс недействителен, либо токен истек. В этом случае клиент немедленно вызовет
renew
конечную точку, если он возвращает 200, то токен обновляется, но еслиrenew
также возвращается 401, то это означает, что клиент находится вне системы.
Какой из двух вышеуказанных вариантов вы бы порекомендовали? Какой из них будет более стандартным, более простым для понимания и / или более RESTful? Или вы бы порекомендовали другой подход вообще? Видите ли вы какие-либо очевидные проблемы или угрозы безопасности с любым из вариантов? Дополнительные баллы, если ваш ответ включает внешние ссылки, которые поддерживают ваше мнение.
ОБНОВИТЬ
Ребята, пожалуйста, обратите внимание на реальный вопрос - какой из двух вариантов кода http для сигнализации о возобновлении / аннулировании сессии является лучшим? Не берите в голову тот факт, что моя система использует JWT и сеансы на стороне сервера, это особенность моего API для очень специфических бизнес-правил, а не та часть, для которой я ищу помощь;)
источник
Ответы:
Это звучит как случай аутентификации против авторизации .
JWT - это криптографически подписанные заявления об отправителе запроса. JWT может содержать утверждения типа «Этот запрос предназначен для пользователя X» и «Пользователь X имеет роли администратора». Получение и предоставление этого доказательства с помощью паролей, подписей и TLS является областью аутентификации - доказательство того, кем вы являетесь.
Что эти утверждения значат для вашего сервера - что могут делать конкретные пользователи и роли - это проблема авторизации . Разница между ними может быть описана двумя сценариями. Предположим, что Боб хочет войти в секцию ограниченного хранения на складе своей компании, но сначала он должен иметь дело с охранником по имени Джим.
Сценарий А - Аутентификация
Сценарий B - Авторизация
Время истечения JWT - это устройство аутентификации, используемое для предотвращения их кражи другими лицами. Если у всех ваших JWT есть пять минут истечения, это не так уж важно, если их украдут, потому что они быстро станут бесполезными. Однако правило «истечения сеанса», которое вы обсуждаете, звучит как проблема авторизации. Некоторое изменение в состоянии означает, что пользователю X больше не разрешено делать то, что он имел обыкновение делать. Например, пользователь Боб мог быть уволен - не имеет значения, что его значок говорит, что он больше Боб, потому что просто быть Бобом больше не дает ему никаких полномочий в компании.
Эти два случая имеют разные коды ответов HTTP:
401 Unauthorized
и403 Forbidden
. К сожалению, названный код 401 предназначен для проблем аутентификации, таких как отсутствующие, просроченные или аннулированные учетные данные. 403 для авторизации, когда сервер точно знает, кто вы, но вам просто не разрешено делать то, что вы пытаетесь сделать. В случае удаления учетной записи пользователя попытка что-либо сделать с JWT в конечной точке приведет к ответу 403 Запрещено. Однако, если срок действия JWT истек, правильный результат будет 401 Unauthorized.Распространенный шаблон JWT - иметь «долгоживущие» и «недолговечные» токены. Долгоживущие токены хранятся на клиенте как краткосрочные токены, но они ограничены по объему и используются только с вашей системой авторизации для получения краткосрочных токенов. Долгоживущие токены, как следует из названия, имеют очень большой срок действия - вы можете использовать их для запроса новых токенов в течение нескольких дней или недель подряд. Краткосрочные токены - это токены, которые вы описываете и используются с очень коротким сроком действия для взаимодействия с вашей системой. Долгоживущие токены полезны для реализации функциональности Remember Me, поэтому вам не нужно вводить пароль каждые пять минут, чтобы получить новый краткосрочный токен.
Проблема «аннулирования сеанса», которую вы описываете, похожа на попытку аннулировать долгоживущий JWT, поскольку недолговечные редко сохраняются на стороне сервера, а долгоживущие отслеживаются на случай, если их нужно отозвать. В такой системе попытка получить учетные данные с помощью аннулированного долгоживущего токена приведет к 401 несанкционированному доступу, поскольку технически пользователь может получить учетные данные, но используемый ими токен не подходит для этой задачи. Затем, когда пользователь пытается получить новый долгоживущий токен, используя свое имя пользователя и пароль, система может ответить 403 Запрещено, если его выгнали из системы.
источник
Ваш сеанс API - это то, чего вообще не должно быть в мире RESTful. Предполагается, что операции RESTful не имеют состояния, сессия содержит состояние и, следовательно, не имеет места в мире RESTful.
JWT должен быть вашим единственным способом определить, имеет ли пользователь право на доступ к конечной точке или нет. Сессия не должна играть абсолютно никакой роли в этом. Если это так, у вас нет RESTful API.
Когда вы полностью исключаете сеанс, что, если вы стремитесь использовать RESTful API, и должны использовать только JWT в качестве фактора аутентификации, пользователь либо авторизуется использовать вашу конечную точку, либо нет - в этом случае
401 Unauthorized
код ответа является подходящим - и должен позвонитьrenew
конечной точке сgrant_type=refresh_token
или каким-либо другим идентификатором продления, которое вы используете.Обновить:
Из комментария кажется, что поток проверки JWT, который вы используете в данный момент, неверен. Проверка должна выглядеть так:
Сервер
RESTful API
должен проверить действительность токена, который отправляется в качестве Авторизации. Это не ответственностьClient
. Похоже, что вы в настоящее время не делаете этого. Внедрите проверку JWT таким образом, и вам вообще не понадобятся сеансы.источник
Итак, я признаюсь, что для меня не имеет большого смысла беспокоиться о том, какой подход является наиболее RESTful, когда вы уже нарушаете соглашения REST во время сеанса, но я понимаю, что удовлетворение ваших бизнес-требований.
С точки зрения REST, клиент либо аутентифицирован, либо нет. Архитектура не заботится о том, почему (это впрыскивает ненужное состояние), поэтому, чтобы ответить на ваш главный вопрос, у меня вообще не будет обновленной конечной точки. Зарегистрированный клиент просто всегда отправляет свой JWT, и сервер всегда проверяет его и либо принимает, отправляя соответствующий код успеха на основе действия 200, 201 и т. Д.), Либо отклоняет его с помощью 401 или 403 в зависимости от ситуации.
Теперь JWT будет связан с какой-то учетной записью. Эта учетная запись может быть заблокирована или заблокирована или что-то подобное, поэтому сам токен может быть действительным, но действие все равно будет отклонено в другом месте. Если дело в том, что учетная запись пользователя заблокирована из-за бизнес-правил, то это по-прежнему 401 или 403, в зависимости от того, сколько информации вы хотите предоставить клиенту (разные предприятия имеют разные мнения по этому поводу).
Наконец, если вы утверждаете, что учетная запись может быть разблокирована и действительна, но JWT просто необходимо отозвать, то я ВСЕ ЕЩЕ придерживаюсь 401 или 403 и поддерживаю что-то вроде Списка отзыва сертификатов недействительных JWT, которые вы можете поместить в до тех пор, пока он очищается, когда истечет время JWT (у большинства баз данных есть способ сделать это, или у вас могут быть события в коде приложения).
источник