Братья внешней аутентификации: cookie, сеанс, токен, jwt, единый вход

HTTP

В этой статье вы найдете:

  • Фронтенд-аутентификация на основе HTTP
  • Почему файл cookie является наиболее удобным решением для хранения и как можно работать с файлом cookie?
  • Как реализована схема сеанса и в чем проблемы
  • Как реализована схема токена, как она кодируется и защищена от несанкционированного доступа? что делает jwt? Реализация и значение токена обновления
  • Каковы сходства и различия между сессией и токеном, их преимущества и недостатки
  • Что такое единый вход? Идеи реализации и обработка в браузере

Небольшое объявление: долгосрочный толчок Didi:why318why@gmail.com


от государства

HTTP не имеет состояния

Мы знаем, что HTTP не имеет состояния. Другими словами, состояние между запросчиком HTTP и ответчиком не может поддерживаться, все это одноразово, и он не знает, что случилось с предыдущим запросом.

Но в некоторых сценариях нам нужно поддерживать состояние. Чаще всего, когда пользователь входит в Weibo, публикация, подписка и комментирование должны осуществляться в состоянии пользователя, вошедшего в систему.

отметка

Итак, каково решение? ::отметка::.

В школе или компании ваша личность и данные учетной записи будут вводиться со дня поступления в школу, а затем вам будет выдана карта.В дальнейшем вам нужно будет только провести этой картой для контроля доступа, перфо- в, и расход в парке.

внешнее хранилище

Это включает в себя одну отправку, одно сохранение, одну область, одну отправку, одну простую в обращении, а интерфейс входа в систему напрямую возвращается во внешний интерфейс, а переднему концу необходимо найти способ для хранения.

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

Есть много способов сохранить переднюю часть.

  • Самое наглое - повесить его на глобальную переменную, но это "карточка опыта", и она пропадет, как только вы обновите страницу
  • Высококачественные хранятся в файлах cookie, localStorage и т. Д. Это «членская карта». Независимо от того, как вы ее обновляете, пока браузер не очищен или не просрочен, он всегда будет удерживать это состояние.

Интерфейсное хранилище здесь не расширяется.

Есть куда сохранить, а при запросе можно прописать в параметры и вывести в интерфейс.


Краеугольный камень: печенье

Но передняя часть настолько хлопотна, что вы должны сохранить ее сами, и вы должны найти способ убрать ее.Есть ли что-нибудь, о чем вам не нужно беспокоиться?

Да, печеньки.

Файлы cookie также являются типом внешнего хранилища, но по сравнению с другими методами, такими как localStorage, с помощью заголовков HTTP и возможностей браузера файлы cookie могут не знать о внешнем интерфейсе.

Общий процесс таков:

  • В интерфейсе, предоставляющем разметку, непосредственно "отправить" в браузер через поле Set-Cookie в заголовке возврата HTTP.
  • Когда браузер инициирует запрос, он автоматически передает файл cookie интерфейсу через поле Cookie заголовка HTTP-запроса.

Конфигурация: домен/путь

Вы не можете поступить в Пекинский университет с картой кампуса Цинхуа.

Файл cookie предназначен для ограничения :: «области пространства» :: через уровень домена (домен) / путь (путь).

Атрибут Domain указывает, какие домены должны быть прикреплены к этому файлу cookie, когда браузер отправляет HTTP-запрос. Если это свойство не указано, браузер по умолчанию установит его как доменное имя первого уровня текущего URL-адреса, напримерwww.example.comОн будет установлен на example.com, и если вы посетите какой-либо поддомен example.com в будущем, HTTP-запрос также будет содержать этот файл cookie. Если доменное имя, указанное сервером в поле Set-Cookie, не принадлежит текущему доменному имени, браузер отклонит cookie.

Свойство Path указывает, к каким путям прикреплять этот файл cookie, когда браузер делает HTTP-запрос. Если браузер обнаружит, что атрибут Path является первой частью пути HTTP-запроса, он добавит этот файл cookie в информацию заголовка. Например, если атрибут PATH имеет значение /, то путь запроса /docs также будет включать файл cookie. Конечно, предполагается, что доменное имя должно быть непротиворечивым.

——Файлы cookie — стандартное справочное руководство по JavaScript (альфа-версия)

Конфигурация: Expires/Max-Age

После окончания обучения карта работать не будет.

Файл cookie также может ограничивать ::"временной диапазон":: через один из Expires, Max-Age.

Атрибут Expires указывает конкретное время истечения срока действия, после которого браузер больше не будет сохранять файл cookie. Его значение находится в формате UTC. Если это свойство не задано или имеет значение null, файл cookie действителен только в текущем сеансе. После закрытия окна браузера и завершения текущего сеанса файл cookie будет удален. Кроме того, браузер определяет, истекает ли срок действия файла cookie по местному времени.Поскольку местное время является неточным, невозможно гарантировать, что срок действия файла cookie истечет во время, указанное сервером.

Атрибут Max-Age указывает количество секунд, в течение которых файл cookie будет существовать с этого момента, например 60 * 60 * 24 * 365 (т. е. один год). По истечении этого времени браузер больше не будет хранить этот файл cookie.

Если Expires и Max-Age указаны одновременно, значение Max-Age будет иметь приоритет.

Если в поле Set-Cookie не указан атрибут Expires или Max-Age, то этот файл cookie является файлом cookie сеанса, то есть существует только в этом сеансе.После того как пользователь закроет браузер, браузер не сохранит этот файл cookie.

——Файлы cookie — стандартное справочное руководство по JavaScript (альфа-версия)

Конфигурация: безопасный/только HTTP

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

Файл cookie может ограничивать ::"использование"::.

Атрибут Secure указывает, что браузер может отправлять этот файл cookie на сервер только по зашифрованному протоколу HTTPS. С другой стороны, если текущим протоколом является HTTP, браузер автоматически проигнорирует атрибут Secure, отправленный сервером. Это свойство является просто переключателем, значение указывать не нужно. Этот переключатель автоматически включается, если связь осуществляется по протоколу HTTPS.

Атрибут HttpOnly указывает, что файл cookie нельзя получить с помощью сценариев JavaScript, главным образом потому, что атрибут Document.cookie, объект XMLHttpRequest и API запросов не могут получить этот атрибут. Это предотвращает чтение файла cookie сценарием, и файл cookie включается только тогда, когда браузер делает HTTP-запрос.

——Файлы cookie — стандартное справочное руководство по JavaScript (альфа-версия)

Заголовки HTTP для чтения и записи файлов cookie

Оглядываясь назад, как HTTP записывает и доставляет файлы cookie и их конфигурацию?

Заголовок Set-Cookie, возвращаемый HTTP, используется для записи «одного (и только одного)» файла cookie в браузер в формате ключ файла cookie + ключ конфигурации. Например:

Set-Cookie: username=jimu; domain=jimu.com; path=/blog; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

А что, если я хочу установить несколько файлов cookie одновременно? Дайте несколько заголовков Set-Cookie (повторение разрешено в одном HTTP-запросе)

Set-Cookie: username=jimu; domain=jimu.com
Set-Cookie: height=180; domain=me.jimu.com
Set-Cookie: weight=80; domain=me.jimu.com

Заголовок cookie HTTP-запроса используется браузером для отправки на сервер всех файлов cookie, соответствующих текущей конфигурации «пространство, время, использование». Поскольку решение о проверке принимается браузером, нет необходимости возвращать содержимое конфигурации, если отправляется значение ключа.

Cookie: username=jimu; height=180; weight=80

Интерфейсное чтение и запись файлов cookie

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

передачаdocument.cookieФайлы cookie можно создавать и изменять, как и HTTP, один раз.document.cookieМожет работать только на одном cookie.

document.cookie = 'username=jimu; domain=jimu.com; path=/blog; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly';

передачаdocument.cookieВы также можете читать файлы cookie, и, как и HTTP, вы можете читать все не-HttpOnlyпеченье.

console.log(document.cookie);
// username=jimu; height=180; weight=80

(Просто атрибут cookie, почему поведение чтения и записи отличается? Получить/установить, чтобы понять)

Файлы cookie являются краеугольным камнем поддержания состояния HTTP-запроса.

После понимания файлов cookie мы знаем, что файлы cookie — это наиболее удобный способ поддерживать состояние HTTP-запросов, и большинство проблем с внешней аутентификацией решаются с помощью файлов cookie. Конечно, можно использовать и другие методы хранения (более или менее упомянутые позже).

Что дальше с инструментами для хранения?


Схема приложения: серверная сессия

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

На самом деле, на вашей карте хранится только один идентификатор (вероятно, ваш студенческий номер).Когда вы проводите пальцем, система свойств проверяет вашу информацию и учетную запись, а затем решает: «Можно ли войти в эту дверь?» идти списывать деньги?».

Эта операция во внешних и внутренних системах аутентификации называется сеансом.

Типичный процесс входа/аутентификации сеанса:

  • Вход в браузер отправляет пароль учетной записи, сервер проверяет базу данных пользователей и проверяет пользователя
  • Сервер сохраняет статус входа пользователя в качестве сеанса и генерирует идентификатор сеанса.
  • Вернитесь через интерфейс входа и установите sessionId в файл cookie.
  • После этого браузер снова запрашивает бизнес-интерфейс, и вместе с кукой приводится sessionId
  • Сервер проверяет sessionId, чтобы подтвердить сеанс
  • После успеха обработайте бизнес в обычном режиме и верните результат.

Метод хранения сеанса

Очевидно, что сервер присваивает cookie только идентификатор сеанса, а конкретное содержимое сеанса (которое может включать информацию о пользователе, статус сеанса и т. д.) должно храниться отдельно. Есть несколько способов хранения:

  • Redis (Рекомендуется): База данных памяти,официальный сайт Redis на китайском языке. Хранится в виде ключ-значение, что и есть сцена sessionId-sessionData, и доступ быстрый.
  • Память: прямо в переменную. После перезапуска службы она исчезла
  • База данных: обычная база данных. Производительность не высокая.

Истечение срока действия и уничтожение сеанса

Очень просто, просто уничтожьте сохраненные данные сеанса.

Распределенные проблемы сеанса

Обычно сервер представляет собой кластер, и пользовательские запросы проходят балансировку нагрузки один раз, не обязательно, какая машина поражена. Затем, когда машина, запрошенная последующим интерфейсом пользователя, несовместима с машиной, которую он запросил для входа, или машина, запрошенная для входа, не работает, не будет ли сеанс недействительным?

Сейчас есть несколько решений этой проблемы.

  • Во-первых, с точки зрения «хранения» сеанс хранится централизованно. Если мы используем отдельный Redis или обычную базу данных, мы можем хранить все сессии в библиотеке.
  • Второй — с точки зрения «распределения», когда запросы с одного и того же IP-адреса отправляются на один и тот же компьютер во время балансировки нагрузки. Возьмите nginx в качестве примера, вы можете настроить ip_hash для достижения этой цели.

Однако обычно используется первый способ, поскольку второй способ равносилен кастрации балансировки нагрузки, и все равно не решает проблему «запрошенная пользователем машина не работает».

Обработка сеанса в node.js

Предыдущая картина очень понятна, серверу нужно реализовать доступ к кукам и сессиям, и еще много чего нужно сделать. существуетnpm, уже есть инкапсулированное промежуточное ПО, такое какexpress-session - npm, использование не будет опубликовано.

Вот такое печенье:

express-session - npmВ основном достигнуто:

  • Он инкапсулирует операции чтения и записи файлов cookie и предоставляет поля конфигурации, методы шифрования, время истечения срока действия и т. д.
  • Он инкапсулирует операцию доступа к сеансу и предоставляет элементы конфигурации для настройки метода хранения сеанса (память/redis), правил хранения и т. д.
  • Предоставляет атрибут сеанса для req, управляет набором/получением атрибутов и отвечает на файлы cookie и доступ к сеансу, а также предоставляет некоторые методы для req.session.

Схема применения: токен

Обслуживание сессии доставило много хлопот серверу, нам нужно найти место для ее хранения, и мы должны рассмотреть проблему распределения, и даже включить для нее набор кластера Redis. Есть ли способ лучше?

Я снова подумал о школе.До технологии кампусных карт мы все полагались на «студенческий билет». Швейцар напрямую проверил лица на студенческом билете и меня, чтобы подтвердить срок действия студенческого билета, оценку и другую информацию, а затем ему разрешили пройти.

Оглядываясь назад, вы не должны хранить слишком много в сеансе для сценария входа, так почему бы не упаковать его непосредственно в файл cookie? Таким образом, серверу не нужно сохранять, и каждый раз, когда вам нужно только проверять действительность «сертификата», содержащегося в файле cookie, вы также можете передавать некоторую облегченную информацию.

Этот метод обычно называют токеном.

Токен поток выглядит следующим образом:

  • Пользователь регистрируется, сервер проверяет пароль учетной записи и получает информацию о пользователе
  • Кодировать информацию о пользователе и конфигурацию токена в токены и отправлять их в браузер через набор файлов cookie.
  • После этого пользователь запрашивает бизнес-интерфейс и переносит токен через куки.
  • Интерфейс проверяет действительность токена и выполняет обычную обработку бизнес-интерфейса.

Как хранится токен клиента

Как упоминалось ранее о файлах cookie, файлы cookie — не единственный способ хранения учетных данных клиентами. Из-за «безгражданства» срок действия и ограничения на использование токена включены в содержимое токена, он меньше зависит от возможности управления файлами cookie, и клиент более свободен в его хранении. Но основной способ для веб-приложений по-прежнему заключается в том, чтобы поместить их в файлы cookie, в конце концов, не беспокойтесь.

Срок действия токена

Итак, как мы контролируем срок действия токена? Это очень просто, просто введите «время истечения срока действия» вместе с данными и оцените его при проверке.

кодировка токена

Способ кодирования экономичен людьми.

base64

Например, на стороне узлаcookie-session - npmбиблиотека

Не беспокойтесь о названии, на самом деле это библиотека токенов, но она сохраняетexpress-session - npmВысоко последовательное использование, зависание данных для сохранения в сеансе

В конфигурации по умолчанию, когда я даю ему идентификатор пользователя, он будет сохранен следующим образом:

здесьeyJ1c2VyaWQiOiJhIn0=,то есть{"userid":"abb”}только base64.

Защита от несанкционированного доступа

Затем возникает проблема, если пользователь cdd берет{"userid":"abb”}Я переключился на base64, а затем вручную изменил свой токен наeyJ1c2VyaWQiOiJhIn0=, можно ли получить прямой доступ к данным abb?

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

解决方案就是给 token 加签名,来识别 token 是否被篡改过。 Например, вcookie-session - npmВ библиотеке добавляем две конфигурации:

secret: 'iAmSecret',
signed: true,

Это создаст множество файлов cookie .sig, значение внутри которых равно{"userid":"abb”}а такжеiAmSecretРассчитывается с помощью алгоритма шифрования, такого какКласс HMACSHA256 (System.Security.Cryptography) | Microsoft Docs.

Ну, теперь cdd может подделать этоeyJ1c2VyaWQiOiJhIn0=, но не может подделать содержимое sig, потому что не знает секрета.

JWT

Однако описанный выше подход увеличивает количество файлов cookie, а сами данные не имеют стандартизированного формата, поэтомуJSON Web Token Introduction - jwt.ioВыключен.

JSON Web Token (JWT) — это открытый стандарт, определяющий способ передачи информации JSON. Эта информация имеет цифровую подпись для обеспечения надежности.

Это зрелая схема генерации строки токена, которая включает в себя данные и подписи, о которых мы упоминали ранее. Давайте посмотрим, как выглядит токен JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiJhIiwiaWF0IjoxNTUxOTUxOTk4fQ.2jf3kl_uKWRkwjOP6uQRJFqMlwSABcgqqcJofFH5XCo 

Как возникла эта череда вещей? Посмотрите на картинку:

Тип, параметры алгоритма шифрования и стандартные поля данных JWT, вы можете обратиться кRFC 7519 - JSON Web Token (JWT)

На узле также есть соответствующие реализации библиотек:express-jwt - npm koa-jwt - npm

refresh token

Токен, как хранитель разрешений, важнее всего «безопасность».

Токен, используемый бизнес-интерфейсом для аутентификации, мы называем токеном доступа. Чем более чувствительный к разрешениям бизнес, тем больше мы надеемся, что срок действия токена доступа будет достаточно коротким, чтобы избежать кражи. Однако, если срок действия слишком короткий, срок действия токена доступа часто истекает.Что мне делать после истечения срока его действия?

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

Другой способ — иметь другой токен, токен, специально сгенерированный для токена доступа, который мы называем токеном обновления.

  • Токен доступа используется для доступа к бизнес-интерфейсу.Поскольку срок действия достаточно короткий, риск незаконного присвоения невелик, а метод запроса также можно сделать более свободным и гибким.
  • Токен обновления используется для получения токена доступа, срок действия может быть больше, а безопасность повышается за счет независимых сервисов и строгих методов запроса, из-за нечастой проверки также может обрабатываться как предыдущая сессия.

С токеном обновления процесс запроса в ряде случаев становится таким:

Если срок действия токена обновления также истек, вы сможете снова войти в систему.

сессия и токен

Как сеансы, так и токены — понятия с очень расплывчатыми границами.Как упоминалось ранее, токены обновления также могут быть организованы и поддерживаться в виде сеансов.

В узком смысле мы обычно думаем, что сессия — это схема аутентификации, которая «подсаживается на куки, а данные хранятся на сервере», а токен — это схема аутентификации, которая «может храниться где угодно на клиенте, и данные хранятся в токене». Сравнение между сеансом и токеном, по сути, является сравнением «клиент хранит файлы cookie/хранит в другом месте» и «сервер хранит данные/не хранит данные».

Клиент сохраняет куки / где-то еще

Удобно и не париться о сохранении куки, но проблема тоже очевидна:

Если вы храните его в другом месте, вы можете решить сценарий без файлов cookie, вручную привести его через параметры и т. д., вы можете избежать CSRF-атак.

Сервер сохраняет данные/не сохраняет данные

  • Хранение данных: запрос должен содержать только идентификатор, что может значительно сократить длину строки аутентификации и уменьшить размер запроса.
  • Без хранения данных: не требует полного набора решений и распределенной обработки на стороне сервера, что снижает затраты на оборудование, позволяет избежать задержек проверки, вызванных проверкой базы данных

войти

Как мы уже видели ранее, в системе аутентификации клиент/сервер в одном и том же домене клиент несет учетные данные для поддержания состояния входа в систему в течение определенного периода времени.

Но когда у нас будет все больше бизнес-линий, будет больше бизнес-систем, разбросанных по разным доменным именам, и нам нужна возможность «одного логина, универсального доступа», которая называется «единый вход».

Поддельный единый вход (то же основное доменное имя)

Просто, если, например, все бизнес-системы находятся под одним и тем же основным доменным именем.wenku.baidu.com tieba.baidu.com, просто хорошо. Вы можете напрямую установить домен cookie в качестве основного доменного имени.baidu.com, Baidu делает то же самое.

«Настоящий» единый вход (другое основное доменное имя)

Например, у такой модной компании, как Didi, есть и то, и другое.didichuxing.com xiaojukeji.com didiglobal.comи другие доменные имена, все виды файлов cookie совершенно неизбежны.

Это настоящий единый вход, если он может обеспечить «один вход в систему, универсальный доступ по всем направлениям».

В этом сценарии нам нужна независимая служба аутентификации, обычно называемая SSO.

Полный процесс «инициации входа в систему из системы A без входа в систему B»

  • Пользователь входит в систему A без учетных данных для входа (тикета), и система A переходит к SSO за него.
  • Если вы не вошли в систему с SSO, в системе sso нет сертификата (обратите внимание, что это отличается от предыдущего билета A), введите пароль учетной записи для входа
  • Если проверка пароля учетной записи SSO прошла успешно, интерфейс возвращается, чтобы сделать две вещи: во-первых, ввести учетные данные в систему SSO (записать статус входа пользователя в SSO); во-вторых, выдать билет
  • Клиент получает билет, сохраняет его и запрашивает интерфейс системы А.
  • Система А проверяет билет и обрабатывает бизнес-запрос в обычном режиме после успешного выполнения.
  • В это время пользователь входит в систему в системе B впервые и не имеет учетных данных для входа (билет), а система B переходит на SSO для него.
  • Если вы вошли через SSO, учетные данные в системе есть, повторно авторизоваться не нужно, достаточно оформить тикет
  • Клиент получает билет, сохраняет его и запрашивает интерфейс системы B.

Полная версия: рассмотрим сценарий браузера

Вышеупомянутый процесс не представляет проблемы, на самом деле этого достаточно для многих приложений и других терминалов. Но это не очень хорошо работает в браузере.

Смотри сюда:

Как для браузера должны храниться данные, возвращаемые в домене SSO, чтобы их можно было принести при посещении A? Браузеры имеют строгие ограничения на междоменные, куки, localStorage и другие методы имеют доменные ограничения.

Для этого требуется возможность хранить учетные данные в домене A, который может быть предоставлен только A. Как правило, мы делаем:

На рисунке цветом отмечаем доменное имя, на котором в данный момент находится браузер. Обратите внимание на изменение описательной части текста на сером фоне на рисунке.

  • В домене SSO SSO не возвращает билеты напрямую через интерфейс, а перенаправляет их на интерфейс системы А через URL с кодом, который обычно согласовывается при регистрации А в SSO.
  • Браузер перенаправляется на домен A и обращается к интерфейсу обратного вызова A с кодом, а интерфейс обратного вызова обменивается билетом с кодом.
  • Этот код отличается от билета, код одноразовый, указан в URL-адресе, просто чтобы передать билет на изменение, после изменения он будет недействителен.
  • После того, как интерфейс обратного вызова получит билет, успешно установите cookie в своем собственном домене.
  • В последующих запросах нужно только разобрать тикет в куке и зайти в SSO для проверки.
  • То же самое касается доступа к системе B.

Суммировать

  • HTTP не имеет состояния, для поддержки передних и обратных запросов требуются внешние теги хранилища.
  • Файлы cookie — это идеальный способ маркировки, он работает через HTTP-заголовок или js, имеет соответствующие политики безопасности и является краеугольным камнем большинства схем управления состоянием.
  • Сессия — это схема управления состоянием: фронтенд хранит id через куки, а бэкэнд хранит данные, но бэкенду приходится иметь дело с распределенными проблемами
  • Токен — это еще одно решение для управления состоянием. По сравнению с сессией, он не требует внутреннего хранилища. Все данные хранятся во внешнем интерфейсе, освобождая серверную часть и предоставляя гибкость.
  • Технология кодирования токена, обычно основанная на base64, или добавление алгоритма шифрования для предотвращения подделки, jwt является зрелой схемой кодирования.
  • В сложных системах токены могут быть децентрализованы с помощью токенов службы и токенов обновления, обеспечивая при этом безопасность и удобство работы пользователей.
  • Сравнение между сеансом и токеном — это сравнение между «использовать или не использовать файл cookie» и «существует ли он в бэкэнде».
  • Единый вход требует, чтобы системы в разных доменах «входили один раз и использовали его по всем направлениям». Обычно независимая система SSO записывает статус входа и выдает билеты, и каждая бизнес-система взаимодействует для хранения и аутентификации билетов.