Русские Блоги
Обмен сообщениями между документами HTML5 (postMessage)
Предисловие
По соображениям безопасности и конфиденциальности веб-браузеры не позволяют документам в разных доменах влиять друг на друга; то есть межсайтовые сценарии не разрешены. Но во многих случаях требуются междоменные операции, поэтому разработаны междоменные методы document.domain, JSONP, CORS и т. Д., Чтобы разрешить междоменные операции. Эти междоменные методы имеют определенные ограничения. Например, я недавно столкнулся с междоменной проблемой. Я открыл веб-страницу www.B.com в домене www.A.com. После завершения операции с URL-адресом B внешний интерфейс уведомил A URL. Ни один из вышеперечисленных методов не может эффективно перекрестного общения.
И тогда я проверил документ и обнаружил, что HTML5 предоставляет новый междоменный метод под названиемОбмен сообщениями между документами, Это функция связи и отправки информации между веб-страницами. Используя эту функцию, пока вы получаете экземпляр объекта окна, где расположена веб-страница, не только веб-страницы одного и того же происхождения (домен + номер порта) могут взаимодействовать друг с другом, и даже может быть реализовано междоменное взаимодействие. Если вы хотите получать информацию, отправляемую из других окон, вы должны отслеживать событие сообщения объекта окна, и другие окна могут передавать данные через метод postMessage.
Применение
1. Предварительное условие Доменное имя использует window.open для открытия сайта доменного имени B.
2. Доменное имя B отправляет сообщение "HI" пользователю "http://www.A.com“。
3. После того, как домен получит сообщение, анализ будет "http://www.B.com"Верни обратно" Я в порядке ", отдай"http://www.A.com“。
Отправить сообщение -postMessage
postMessage отвечает за отправку сообщений и публикацию сообщений в заданном окне. Сообщения могут быть структурированными объектами.
Метод postMessage (data, origin) принимает два параметра:
Поле | Введение |
---|---|
data | В спецификации html5 упоминается, что параметр может быть любым базовым типом JavaScript или воспроизводимым объектом, но не все браузеры делают это, а некоторые браузеры могут обрабатывать только строковые параметры, поэтому мы При передаче параметров вам необходимо использовать метод JSON.stringify () для сериализации параметров объекта. Для достижения аналогичного эффекта вы можете использовать json2.js в более ранних версиях IE. |
origin | Параметр String, укажите источник целевого окна, протокол + хост + номер порта [+ URL], URL-адрес будет проигнорирован, поэтому его не нужно писать, этот параметр из соображений безопасности, метод postMessage () будет передавать сообщение только в указанное окно Конечно, если вы хотите, вы также можете установить параметр на «*», который может быть передан в любое окно. Если вы хотите указать тот же источник, что и текущее окно, установите его на «/». |
Получить сообщение-событие
окно новое сообщение о событии, отвечающее за сбор информации. Получите информацию с его веб-сайта, опубликовав метод сообщения. postMessage (сообщение, targetOrigin [, передача])
window.addEventListener(‘message’, function(e)
, false);
// Это приемник для получения вывода информации.window.attachEvent(‘message’, function(e)
, false);
// Используйте attachEvent ниже IE9
Полученный объект использует следующие атрибуты.
Есть несколько важных атрибутов
Поле | Введение |
---|---|
data | Получите значение, переданное сообщением, тип значения — строка. |
source | Объект окна, отправляющий сообщение. |
origin | Источник окна сообщения (протокол + хост + номер порта). |
безопасность
Вы должны быть очень осторожны при использовании этого API, потому что это точка входа, которая позволяет всем отправлять информацию.
Следовательно, атрибут origin должен быть установлен при использовании сообщения, чтобы гарантировать информацию о разрешенном домене. Избегайте предоставления других вредоносных URL-адресов для использования атак.
И postMessage () также необходимо установить источник, чтобы предотвратить получение сообщения другими веб-сайтами без авторизации. Не рекомендуется устанавливать (*)
Злоумышленник может отправить большое количество сообщений; если принимающая страница выполняет дорогостоящие вычисления или вызывает отправку сетевого трафика для каждого такого сообщения, сообщения злоумышленника могут умножиться, что приведет к атаке отказа в обслуживании. Поощряйте использование ограничения скорости (принимайте только определенное количество сообщений в минуту), чтобы сделать эту атаку непрактичной.
совместимость
Браузер Chrome 64+
Chrome 4+
iOS Safari 3.2+
Браузер UC Android 11.8+
Firefox 3+
Браузер IE (с ограничениями) 8+
Samsung Internet 4+
Opera Mini все +
Safari 4+
Edge 12+
Android Browser 2.1 +
Opera 9.5+
Источник: caniuse.com
Внимание событие
1. Cross-Document Messaging подходит для использования окон для передачи значений друг другу, но если вы хотите перейти на страницу, это будет ограничено безопасностью браузера. (Ограничения браузера IE не могут перенаправлять с других доменов)
2. Использование требует четкого понимания взаимосвязи окон, чтобы значение могло быть передано правильно.
Нельзя просто так взять и обратиться к фоновой странице
Всё дело — в политике безопасности, аналогичной кроссдоменной. Обращение к страницам других табов или к фоновой странице расширения сознательно ограничено, потому что они считаются страницами других доменов, имеют запреты на прямой доступ к скриптовому окружению, аналогично чужим окнам и фреймам. Механизм сообщений «спасает» как при кроссдоменном доступе между фреймами, как и в доступе к страницам расширений (фоновая, настройки, попап, . ).
В расширении браузера Google Chrome (и Chromium) наиболее важна по функциям — фоновая страница. Она имеет специальный URL вида chrome-extension://ciegcibjokpkcklhgbpnmnikpkmkhbjk/, где длинное имя домена — случайное имя, создаваемое в недрах браузера, которым именуется также каталог расширения где-то в служебной папке ОС. Из контентного скрипта (аналогичного юзерскриптам, исполняемым на странице браузера) можно получить доступ к файлам и картинкам расширения. Но нельзя выполнить много функций, путь к которым лежит через фоновую страницу: устроить хранилище, относящееся к группе реальных доменных имён; хранить настройки расширения, общие для всего расширения. Нужно лишь добраться в Мордор к фоновой странице. Однако, нельзя просто так, по URL, это сделать.
Данного описания нет на страницах документации к Хрому. Вернее, оно есть, но для «немного других» методов и объектов, что фактически означает — нет, до тех пор, пока не исправили. Поведение описанных объектов для обмена сообщениями подтверждается несколькими примерами в ответах на StackOverflow. Искать ответы каждый раз по разрозненным примерам — утомительно, поэтому, чтобы покончить c этой неразберихой, пусть уж они будут собранными в одном месте здесь. Перебраны все 4 комбинации прямых и обратных вызовов, чтобы перед глазами всегда были работающие шаблоны их.
Для проверки и демонстрации нужно скопировать или создать 3 файла (manifest.json, script.js, background.js), создав тестовое расширение в режиме разработчика в Хроме, и смотреть на сообщения в консоли из 2 страниц — окна браузера с внедрённым скриптом script.js и фоновой (смотреть консоль фоновой background.js — нажав на ссылку «Проверить режимы просмотра: _generated_background_page.html» в chrome://extensions/). То же будет работать в каком-нибудь готовом расширении, если 2 фрагмента кодов из статьи расставить по страницам и выполнить.
На Хабре подобная задача решалась в прикладных целях в habrahabr.ru/post/159145, ноябрь 2012 — те же самые источники знаний, которые молчаливо подправили и использовали. В интернете на русском похожая задача описывалась в статье от июня 2012. Здесь — описан механизм, который используется для решения таких задач, с учётом того, что он выполняется в скриптах расширения браузера Google Chrome.
Если к страницам в окнах и фреймах того же домена получаем доступ напрямую (как к окну другого скриптового окружения), то фоновая страница, равно как и другие табы и страницы браузера, выступают как страницы чужих доменов. Мы можем слать им сообщения, реализуя паттерн слабой связанности процедур, и можем передавать в них лишь объекты, способные к сериализации — никаких DOM, окружений и других сложных объектов.
К фоновой странице есть, из-за чего стремиться. В ней выполняются такие функции, которые в скрипте или юзерскрипте немыслимы. Там — не только память, общая для всех страниц. Там — реализация многих интерфейсов, описанных на developer.chrome.com/extensions/api_index.html, а в будущем ожидается и того больше. В скудном интерфейсе сообщений есть функции-коллбеки, которые, будучи заданными, выполняются в вызывающей функции, на стороне своего окружения, но с параметром-результатом, который передала другая сторона.
Всё это — немного модифицированный интерфейс среды Javascript postMessage, созданный не очень давно в браузерах для решения проблем регламентации кроссдоменного доступа. Обычно он применяется для общения скриптов между окнами и фреймами и остаётся единственным удобным средством общения, если домены страниц — разные. Ранее для решения этой проблемы использовался «костыль» под кодовым именем «window.name», по ключевым словам используемых объектов. Он работает и сейчас, но сложный и, очевидно, медленный, по сравнению с методом postMessage, пришедшим ему на замену. Вспомним, как работает обычный механизм postMessage, потому что на нём основаны механизмы обмена данными в расширении Хрома.
Интерфейс postMessage (кроссбраузерно, IE8+)
Страница-инициатор сообщения создаёт пользовательское событие «message» — делает отправку сообщения, причём делает это не из своего домена, а из того, к которому желает обратиться. (в IE8 есть ограничение — обращение только к родительскому окну фрейма).
Если имя домена угадано, сообщение отправится. Для его приёма в окне otherWindow должна быть выполнена пара условий:
1) существовать обработчик события;
2) обработчик «ждёт» сообщение именно с домена-отправителя и проверяет это через второй аргумент.
Отправляем сообщение из окна в фоновую страницу (Chrome)
В расширениях основу (postMessage) немного переработали, добавив коллбеки и автоматизировав проверки доменов. Стало удобнее, чем если собирать передачу сообщения из кирпичиков. В самом конце приведём код на стандартном postMessage, используя доступные средства, чтобы показать, что магии в следующих описанных sendMessage или sendRequest нет — это просто оболочка. Но postMessage не смог выполниться из-за недостаточных прав расширения на создание фрейма с особым протоколом «chrome-extension://*», про который формат манифест-файла тоже ничего не знает, и дело утонуло в бюрократических проволочках. Вот и ответ на вопрос, почему им пришлось придумать свои функции обмена.
Приведённые примеры можно увидеть, проверить и исследовать их поведение со страницы установки расширения Chrome: spmbt.kodingen.com/bgMessageXmp/index.htm. Если расширение не установлено, клики по 5 ссылкам сообщают об отсутствии расширения. После установки (в расширении — всего 3 необходимых файла) клики начинают выполнять примеры, описанные ниже.
Как установить: 1) скачать архив, 2) распаковать (или сразу инсталлировать), 3) на chrome://extensions/ перейти в «режим разработчика», 4) выполнить «Загрузить распакованное расширение. », выбрав каталог из архива, 5) обновить страницу, с которой загружалось расширение. 5 ссылок готовы к выполнению примеров. После выполнения достаточно удалить скрипт средствами chrome://extensions/. Этот скрипт примеров может быть использован как каркас для тестирования или написания расширений. Для данной статьи он помог отладить скрипты из текста и устранить из них опечатки.
Пример 1.
Если надо отправить из таба в фоновую страницу и на этом закончить, используется простой формат сообщений:
Принимается сообщение в фоновой или любой другой странице:
Пример 2.
Эта пара функций приспособлена для обмена обратным сообщением. Добавляем параметров, из скрипта:
из фоновой страницы:
f_callback — выполняется в скрипте (не в фоновой странице), но с параметром, заданным в фоновой.
Объект sender имеет вид:
Таким образом, из него кое-что известно о том, кто отправил сообщение. Сейчас не будем использовать значений из sender, но возможно отслеживание, из какого таба или окна пришло сообщение, рассылать изменения в другие контентные скрипты, если они есть в других табах.
(конец примера 2)
Если надо передать что-то посложнее — нет проблем встроить хеш или массив вместо строки. Передача хеша вместо набора аргументов — вообще, более продвинутая форма обмена — занимает 1 аргумент, читается легче, так как самодокументирован ключами, значения хеша переставляются и удаляются элементарно — не нужно помнить порядок и беспокоиться об отсутствующих значениях.
С техникой замены аргумента на хеш 3 аргументов хватит на всё, и каждый из них выполняет свою роль. Идя дальше, их можно было бы заменить 1 аргументом, с ключами
Например, нужно отправлять не только имя команды, но и хеш с данными. Пишем из скрипта:
из фоновой страницы:
Укоротим часто повторяющиеся вызовы из контентных страниц:
(Третьего коллбека почему-то не предусмотрено… Управление перебрасывается только 2 раза.)
Отправляем сообщение из фоновой страницы в окно (Chrome)
Пример 3.
Если стоит обратная задача, отправить сообщение из фоновой страницы в, допустим, активный таб:
в фоновой пишем:
Принципиально ли то, что в первом случае использовали пару sendMessage-onMessage, а во втором — sendRequest-onRequest? Нет, работает любой метод, лишь бы он был из одной пары.
Пример 4.
Если нужно отправить сообщение с обратным коллбеком, в фоновой пишем:
Выполняется, как видно — всё, что было описано в документации, но для немного другого объекта (chrome.runtime), на developer.chrome.com/extensions/messaging.html, а chrome.runtime в данной задаче не работает — не имеет метода sendMessage.
Передача на стандартном postMessage (не выполнена)
Несмотря на отрицательный результат, эта попытка передачи подскажет догадки о том, почему разработчикам пришлось заняться собственными функциями передачи данных в расширениях, несмотря на наличие postMessage.
Один из немногих выполнимых в контентном скрипте особых методов расширений — chrome.extension.getURL(‘путь’). Он возвращает путь к ресурсам расширения. Открыв его, получим ресурсы расширения (но не к каталогам) — картинки и тексты из него. Иной домен и здесь сыграет свою роль: чтобы получить тексты в окружение скрипта страницы, нужно делать кроссдоменный Ajax. Или поступить проще — получить тексты через стенку домена механизмом сообщений.
Пример 5.
Передадим сообщение, используя определившийcя протокол («chrome-extension:») с доменом (что-то вида «//ciegcibjokpkcklhgbpnmnikpkmkhbjk»).
Но не всё просто. Доступа к окну фоновой страницы у контентного скрипта нет. Метод есть:
Но доступа нет:
Uncaught Error: «getBackgroundPage» can only be used in extension processes. See the content scripts documentation for more details.
Коммандо не унывает. Для простого обмена ведь надо создать фрейм. Ничего не мешает создать фрейм.
Возникла ошибка:
Denying load of chrome-extension://ciegcibjokpkcklhgbpnmnikpkmkhbjk/. Resources must be listed in the web_accessible_resources manifest key in order to be loaded by pages outside the extension.
Добавляем разрешение в манифест (а при chrome.extension.sendMessage этого было не нужно).
«permissions»:[«chrome-extension://*», . ]
Возникла ошибка на chrome://extensions/:
При установке расширения возникли предупреждения:
Permission ‘chrome-extension://’ is unknown or URL pattern is malformed.
Если бы доступ не был запрещён, осталось бы выполнить
На этом пример можно закончить — он показал, что доступ через штатную функцию закрыли по другим причинам — из-за необходимости просмотра фоновых страниц в фреймах, чего по безопасности, видимо, было недопустимо (в «manifest_version»: 2). Поэтому в расширениях Chrome, но также и по соображениям оптимизации синтаксиса и двунаправленного обмена, были придуманы специальные методы обмена сообщениями.
Общение между окнами
Политика «Одинакового источника» (Same Origin) ограничивает доступ окон и фреймов друг к другу.
Идея заключается в том, что если у пользователя открыто две страницы: john-smith.com и gmail.com , то у скрипта со страницы john-smith.com не будет возможности прочитать письма из gmail.com . Таким образом, задача политики «Одинакового источника» – защитить данные пользователя от возможной кражи.
Политика "Одинакового источника"
Два URL имеют «одинаковый источник» в том случае, если они имеют совпадающие протокол, домен и порт.
Эти URL имеют одинаковый источник:
- http://site.com
- http://site.com/
- http://site.com/my/page.html
А эти – разные источники:
- http://www.site.com (другой домен: www. важен)
- http://site.org (другой домен: .org важен)
- https://site.com (другой протокол: https )
- http://site.com:8080 (другой порт: 8080 )
Политика «Одинакового источника» говорит, что:
- если у нас есть ссылка на другой объект window , например, на всплывающее окно, созданное с помощью window.open или на window из <iframe> и у этого окна тот же источник, то к нему будет полный доступ.
- в противном случае, если у него другой источник, мы не сможем обращаться к его переменным, объекту document и так далее. Единственное исключение – объект location : его можно изменять (таким образом перенаправляя пользователя). Но нельзя читать location (нельзя узнать, где находится пользователь, чтобы не было никаких утечек информации).
Доступ к содержимому ифрейма
Внутри <iframe> находится по сути отдельное окно с собственными объектами document и window .
Мы можем обращаться к ним, используя свойства:
- iframe.contentWindow ссылка на объект window внутри <iframe> .
- iframe.contentDocument – ссылка на объект document внутри <iframe> , короткая запись для iframe.contentWindow.document .
Когда мы обращаемся к встроенному в ифрейм окну, браузер проверяет, имеет ли ифрейм тот же источник. Если это не так, тогда доступ будет запрещён (разрешена лишь запись в location , это исключение).
Для примера давайте попробуем чтение и запись в ифрейм с другим источником:
Код выше выведет ошибку для любых операций, кроме:
- Получения ссылки на внутренний объект window из iframe.contentWindow
- Изменения location .
С другой стороны, если у ифрейма тот же источник, то с ним можно делать всё, что угодно:
Событие iframe.onload – по сути то же, что и iframe.contentWindow.onload . Оно сработает, когда встроенное окно полностью загрузится со всеми ресурсами.
…Но iframe.onload всегда доступно извне ифрейма, в то время как доступ к iframe.contentWindow.onload разрешён только из окна с тем же источником.
Окна на поддоменах: document.domain
По определению, если у двух URL разный домен, то у них разный источник.
Но если в окнах открыты страницы с поддоменов одного домена 2-го уровня, например john.site.com , peter.site.com и site.com (так что их общий домен site.com ), то можно заставить браузер игнорировать это отличие. Так что браузер сможет считать их пришедшими с одного источника при проверке возможности доступа друг к другу.
Для этого в каждом таком окне нужно запустить:
После этого они смогут взаимодействовать без ограничений. Ещё раз заметим, что это доступно только для страниц с одинаковым доменом второго уровня.
Ифрейм: подождите документ
Когда ифрейм – с того же источника, мы имеем доступ к документу в нём. Но есть подвох. Не связанный с кросс-доменными особенностями, но достаточно важный, чтобы о нём знать.
Когда ифрейм создан, в нём сразу есть документ. Но этот документ – другой, не тот, который в него будет загружен!
Так что если мы тут же сделаем что-то с этим документом, то наши изменения, скорее всего, пропадут.
Нам не следует работать с документом ещё не загруженного ифрейма, так как это не тот документ. Если мы поставим на него обработчики событий – они будут проигнорированы.
Как поймать момент, когда появится правильный документ?
Можно проверять через setInterval :
Коллекция window.frames
Другой способ получить объект window из <iframe> – забрать его из именованной коллекции window.frames :
- По номеру: window.frames[0] – объект window для первого фрейма в документе.
- По имени: window.frames.iframeName – объект window для фрейма со свойством name="iframeName" .
Ифрейм может иметь другие ифреймы внутри. Таким образом, объекты window создают иерархию.
Навигация по ним выглядит так:
- window.frames – коллекция «дочерних» window (для вложенных фреймов).
- window.parent – ссылка на «родительский» (внешний) window .
- window.top – ссылка на самого верхнего родителя.
Можно использовать свойство top , чтобы проверять, открыт ли текущий документ внутри ифрейма или нет:
Атрибут ифрейма sandbox
Атрибут sandbox позволяет наложить ограничения на действия внутри <iframe> , чтобы предотвратить выполнение ненадёжного кода. Атрибут помещает ифрейм в «песочницу», отмечая его как имеющий другой источник и/или накладывая на него дополнительные ограничения.
Существует список «по умолчанию» ограничений, которые накладываются на <iframe sandbox src=". "> . Их можно уменьшить, если указать в атрибуте список исключений (специальными ключевыми словами), которые не нужно применять, например: <iframe sandbox="allow-forms allow-popups"> .
Другими словами, если у атрибута "sandbox" нет значения, то браузер применяет максимум ограничений, но через пробел можно указать те из них, которые мы не хотим применять.
Вот список ограничений:
allow-same-origin "sandbox" принудительно устанавливает «другой источник» для ифрейма. Другими словами, он заставляет браузер воспринимать iframe , как пришедший из другого источника, даже если src содержит тот же сайт. Со всеми сопутствующими ограничениями для скриптов. Эта опция отключает это ограничение. allow-top-navigation Позволяет ифрейму менять parent.location . allow-forms Позволяет отправлять формы из ифрейма. allow-scripts Позволяет запускать скрипты из ифрейма. allow-popups Позволяет открывать всплывающие окна из ифрейма с помощью window.open .
Больше опций можно найти в справочнике.
Пример ниже демонстрирует ифрейм, помещённый в песочницу со стандартным набором ограничений: <iframe sandbox src=". "> . На странице содержится JavaScript и форма.
Обратите внимание, что ничего не работает. Таким образом, набор ограничений по умолчанию очень строгий:
JS – Как безопасно использовать window.postMessage, когда домен отправителя неизвестен
Я хотел бы создать безопасное соединение postMessage (безопасное начало), с iframe, созданным во время выполнения.
Текущее состояние:
У меня есть script, который генерирует iframe с определенным доменом ( domain.b.com в примере ниже). Я хочу, чтобы iframe получал сообщения только из родительского домена (страница, которая включала мой script). Поскольку родительский домен неизвестен во время выполнения, я думаю о процессе “Рукопожатия”, как описано и проиллюстрировано ниже:
- Подождите, пока Iframe будет загружен.
- Отправить postMessage из родительского домена с его началом.
- Установите разрешенное начало в качестве первого полученного источника.
Edit:
Дополнительная информация:
- На моем сервере у меня есть домены whitelist (например, domain.a.com, any.domain.com, domain.b.com)
- Моя цель – интегрироваться с некоторыми из моих клиентов (например, domain.a.com, domain.b.com)
- После интеграции я хочу, чтобы хакеры не вводили Iframes, которые могут прослушивать конфиденциальную информацию через postMessage
- Я хочу, чтобы избежать проверки белого списка, я предпочитаю давать некоторые acessToken, но не уверен, что такое правильный поток.
Пример 1:
Пример 2:
Правильно ли это реализовать?
Как уже упоминалось здесь, вам не следует ожидать, что родительское происхождение будет отправлено вам в параметре postMessage . Вместо этого:
Если вы ожидаете получать сообщения с других сайтов, всегда проверяйте идентификатор отправителя, используя свойства происхождение и, возможно, источника. Любое окно (включая, например, http://evil.example.com) может отправлять сообщение в любое другое окно, и у вас нет гарантий того, что неизвестный отправитель не отправит вредоносные сообщения. После проверки однако, вы все равно должны всегда проверять синтаксис получил сообщение. В противном случае, отверстие безопасности на сайте, которому вы доверяете для отправки только доверенных сообщений можно было бы открыть межсайтовый скриптинг на вашем сайте.
И как только у вас есть URI основного фрейма в вашем iframe, вы можете проверить его авторизацию с помощью простого вызова AJAX на сервер. С моей точки зрения, вызов сервера неизбежен, и так или иначе вы сделаете такой вызов.
Есть другие способы узнать, кто включает ваш iframe, но они не полагаются на postMessage . Например, если вы используете PHP, вы можете проверить $_SERVER[‘HTTP_REFERER’] , чтобы узнать, кто запрашивает ваш iframe еще до его отправки в браузер. Тем не менее существуют способы ссылки на спуфинг.
Если вашему приложению требуется твердое решение с пуленепробиваемыми правами, связь между сервером и сервером – это ваш путь. В этом случае каждый ваш клиент имеет имя пользователя и пароль, а веб-сервер, который будет обслуживать главную страницу, должен запросить одноразовый маркер прохождения с веб-сервера, который обслуживает iframe (это связь между сервером и сервером). И затем используйте токен в URL-адресе iframe, который будет отправлен обратно на сервер, сгенерированный им. Здесь шаг за шагом этого сценария:
Конечный пользователь запрашивает URL http://customer.com/main.php .
Пока main.php выполняет и заполняет ответ, он также
подключается к
http://you_website.com/generate_token.php?username=cutomer1&password=123
и получает одноразовый токен token1 .
Ответ возвращается браузеру, содержащему iframe с URL http://your_website.com/iframe.php?token=token1 .
В iframe.php вы проверяете token1 , чтобы убедиться, что он действителен, и
, в то же время вы аутентифицируете запросчика без фактического запроса
для его имени пользователя и/или пароля (поскольку вы знаете, кто у вас есть
генерировал токен для).
Такие токены обычно удаляются после использования (один раз), и они также обычно имеют данные об истечении срока действия. Но это зависит от вас и вашего приложения.