Всерьёз так ни кто не делает, потому, что из всех браузеров отличились разработчики Safari, отказавшись реализовывать расширение нативных элементов. В Safari в целом наследование не от HTMLElement просто не работает.
Семантика пользовательским элементам задаётся двумя способами:
ARIA атрибуты: role, aria-label и т.д. т.п. (Устанавливается либо через сеттеры role, ariaLabel и т.д. Либо через установку атрибута);
Через готовящийся ElementInternals.
По семантике ещё делается "виртуальное дерево" для использования с canvas и д.р.
Это правда. Просто получилось, что те кто понимают суть JAM хотя бы частично, горят что пример только часть JAM'а, а те кто не в теме получили либо не полное, либо ложное понимание. Автор оригинальной статьи тоже "молодец" с его "Нет" серверам, и в середине "Да" серверам.
Автор сам запутался во всех "новых" словах которые он узнал за последние пару лет.
В начале он говорит нет серверам и на середине статьи говорит, а вот JAMstack (у которого на минуточку API это сервера). Т.е. он сам себе противоречит.
SPA/MPA/PWA/CRA/etc, React/Vue/etc. и т.д. и т.п. Если они используют статичные HTML страницы (даже если она одна), используют JavaScript (а всё перечисленное использует его), используют API (а многие всё же делают запросы к API) — всё это JAMstack.
Сам JAMstack далеко не новый, название и реклама да, подход нет. И он не умирал и не умирает, а живёт и процветает, подстраиваясь под 5 лет эволюции веба (на самом деле 10 лет, а если честнее ещё больше). Ключевые JAM: JavaScript API Markup никуда не пропадали.
JavaScript
Dynamic functionalities are handled by JavaScript. There is no restriction on which framework or library you must use.
APIs
Server side operations are abstracted into reusable APIs and accessed over HTTPS with JavaScript. These can be third party services or your custom function.
Markup
Websites are served as static HTML files. These can be generated from source files, such as Markdown, using a Static Site Generator.
JAMstack не противоречит SPA, а даже наоборот. Главный манифест JAM — JavaScript API Markup, а это всё есть почти в любом SPA (есть SPA не использующие API серверов).
На самом деле всё зависит от подхода, можно каждый раз генерировать полностью целый сайт, а можно перегенерировать только изменившиеся страницы (Incremental Build). Это конечно ещё и от инструментов зависит.
Вообще стоит сказать, что JAMstack может быть и без генераторов на самом деле. Если у вас собранная руками html страничка и есть как клиентский JavaScript, так и запросы к API — вы уже используете JAMstack. Даже если страница фактически будет тупо скелетоном это всё ещё JAMstack, хотя больше продвигается "прогрессивный" подход. Тут важно ещё не забывать про клиентскую сторону — мегабайты кода. Всё это всё ещё нужно оптимизировать.
Статически сгенерированные сайты определенно несут преимущества для конечного пользователя. Но стоит помнить, что у всего есть своя цена.
А вот это в рамочку. В зависимости от подхода к JAMstack вы будете платить временем и объёмом хранилища.
Но ведь у вас всё равно в итоге получился не JAMstack. Вы всё ещё используете чисто второй подход скатываясь к первому, только рендер перенесли с on-prem на этап сборки. В итоге на выходе у вас только статическая разметка (пусть и сгенерированная). Это путь всевозможных статических генераторов и только часть JAMstack, даже не половина, а скорее треть.
Чтобы получился действительно настоящий JAMstack нужно скрестить все 3 варианта. Причём даже в статье расшифровка приведена JavaScript API Markup. Т.е. к вашему варианту нужно ещё добавить сервер с API (и вот оно расхождение в статье) и клиентский JavaScript код, тогда у вас будет действительно JAMstack.
Фактически сайты на React/Vue/etc, если используют API, гидрацию и будут собирать страницы в статику именно на этапе сборки — настоящий JAMstack.
Чтобы понять что такое JAMstack, оставлю ссылку на JAMstack.wtf. А вообще всё это довольно олдскульно, даже JAMstack существует далеко не 4 года и не 8.
Вот в этом мы разошлись, я под словом "чувствительные" понимал данные, попадание которых в открытый доступ является проблемой безопасности в том или ином виде. Ровно так же про чувствительность данных в полезной нагрузке трактуется в стандарте, там есть ремарка по поводу использования JWE для этих целей.
То что использование любого средства может быть правильным, неправильным и дико неправильным — мне представляется довольно естественным. Тема с JWT выделяется тем, что примеров дико неправильного использования настолько много, что явно выше 50х50
Тут вопрос скорее такой, что считать правильным, а что не правильным. JWT даёт возможность самому исполнять для конкретной задачи конкретный вариант реализации. Причём иногда этот вариант со стороны может выглядеть как "дико неправильный", но это со стороны и смотря только на верхушку айсберга, что внизу вы явно не знаете.
В конце концов то, что сейчас считается не правильным, через несколько лет может оказаться верным.
Опять таки если мы рассматриваем алгоритмы подписи JWT, среди которых есть hash-only HS* (SHA*) и специальный "none" у которых просто нет пар ключей, аргумент про длину подписи зависящую от длины ключа точно так же опровергается. Подчёркиваю я настаиваю именно на утверждении, что подпись JWT зависит от выбранного алгоритма подписи JWT, если это "none" — длина подписи будет равна 0, если это HS* — будет равна размеру хэш-блока, если это RS*, ES*, PS* будет зависеть от длины ключа т.к. длина результата алгоритмов RSA, ECDSA будет зависеть от длины ключа. Но последнее утверждение не применимо к алгоритмам HS* и "none", именно по этому я настаиваю на связи именно от алгоритма подписи JWT. Не стоит откидывать алгоритмы HS* и "none" для них найдутся применения.
И даже при использовании любой пары RS* (RSA) — RS256 и RS512? Это же именно алгоритмы генерации подписи JWT, различия между ними в алгоритмах генерации хешей SHA256 и SHA512, но одинаковый алгоритм RSA. Ладно длина будет одна, но ключи можно использовать одинаковые как для RS256, так и для RS512. И опять таки это не противоречит тому, что я пишу — длина подписи JWT зависит именно от алгоритма подписи JWT, алгоритм подписи JWT может работать как с ключами RS*, ES*, PS*, так и без ключей HS* и "none". Если использовать разные ключи одинаковой длинны в разных алгоритмах с одинаковой хеш-функцией (например SHA256) длина подписи будет разная и зависеть от самого алгоритма будь то RSA или ECDSA.
И всё-таки не зависит от ключа на прямую, но зависит от алгоритма подписи напрямую.
Я именно об этом, ведь если мы используем не пары ключей, а просто секретную строчку и один из алгоритмов HS* — длина подписи будет зависеть только от выбранного алгоритма, но ни как не от длины секретной строчки. Т.к. тут у нас только хеш.
Если мы используем уже пары ключей, тут уже сами алгоритмы зависят от длины ключей согласен. Но сама подпись опять таки в глобальном смысле зависит именно от алгоритма подписи. Ведь даже если мы будем использовать одинаковые ключи (очевидно с одинаковой длинной), но разные алгоритмы (мы же можем использовать как RS512, так и RS256 с одной и той же парой ключей), то длинна подписи будет разной вне зависимости от одинаковой длинны ключей т.к. величина блоков этих алгоритмов разная.
Мы же ведём речь о стандарте JWT в целом, а он поддерживает множество алгоритмов подписей в т.ч. и не на ключах. Если выбрать указанный алгоритм "none", то подпись будет равна длине 0 (т.е. вовсе отсутствовать).
В конце своего сообщения я указал пример выбора решения использования JWT не смотря на то, что он увеличивает объём трафика и может показаться более жирным чем тупо id + подпись. Главный аргумент — стандартизованный контейнер, об этом даже в самом стандарте написано. JWT это платформо-независимый контейнер токенов, со статусом стандарта. В base64 все вполне умеют в криптографические подписи тоже и в JSON тоже. Его сделали, специально таким гибким и универсальным ведь в большинстве случаев разработка своего формата токенов является задачей сложной, мало сформулировать формат, нужно его внедрить и поддерживать.
Если речь идёт о ваших внутренних сервисах, которые разрабатываете вы лично или небольшая команда, очевидно id + подпись вам будет использовать выгоднее (правда не всегда). Но если речь заходит о том, что это экосистема разрабатываемая огромным количеством независимых людей и взаимодействие не ограничивается только лишь вашими сервисами, то JWT тут побеждает как минимум имея статус стандарта, гибкостью и уже имеющейся интеграцией и поддержкой.
Потом, в моём примере про хранение сессионного id в jti я не писал, что в токене должен храниться только jti, вы можете вполне туда добавить не чувствительные данные (настоятельно подчёркиваю, что не чувствительные данные) пользователя (например логин, аватар, возможно имя и т.д.), в том числе чтобы снизить нагрузку на базу (это к слову является одним из примеров использования в самом стандарте).
Чувствтельные данные в JWT хранить не только можно но и нужно.
Вот с этим поспорю и очень даже сильно. Чувствительные данные в токене вы можете хранить, если используете специальную версию JWE с шифрование, но не JWT. JWT является открытым форматом и именно по этому в полезной нагрузке подчёркнуто нельзя хранить чувствительные данные. Отзыв токена не влияет на доступ к этим данным. Они опубликованы открытым текстом (если не учитывать b64). И этот токен может сохраняться где угодно и сколько угодно и вы даже не будете об этом знать. Данные в нём соответственно тоже. Именно по этому в JWT должны храниться только не чувствительные данные.
Параллельно необходимо продумать систему отзыва токена до выхода срока его действия.
Не во всех сферах и реализациях это необходимо, опять таки мой пример варианта реализации сервиса отзывов JWT. Я там упомянул про использование JWT для отзыва других JWT.
А мысль следующая в JWT в поле субъекта указываете id отзываемого токена, время жизни создаваемого токена для авторизации отзыва минимальна, но достаточна на совершение операции. Подпись такого токена производится закрытым ключём клиента, имеющего возможность отзывать токены. Публичный ключ клиента сервису отзывов так или иначе известен. Подпись в данном случае совместно с идентификатором клиента (в поле полезной нагрузки) являются аутентификационными данными клиента, запрашивающего отзыв токена. Причём в авторизационном токене хранить jti не нужно, его просто на просто не нужно отзывать. Сама операция отзыва может быть произведена явно только один раз, т.к. на последующие запросы с этим токеном мы можем ничего не делать (в реестре уже будет идентификатор отзываемого токена). Тут уже помогает время жизни авторизационного токена, можно ещё в нём указать время жизни отзываемого токена.
Обращаю внимание реализация зависит от нужд, ни что не является обязательным, если в стандарте явно не указано об этом и не аргументировано.
Мне кажется в стандарте явно не указаны примеры "правильных" использований JWT т.к. это своего рода просто стандартизированный контейнер. А сама реализация, набор данных и т.д. — является инженерной задачей, относящейся к конкретной сфере применения. Есть разные задачи с разными подходами применения JWT и наборами данных.
Например, если речь идёт о коммуникации machine-to-machine (по своей сути микро-сервисы), очевидно, что JWT должны работать на парах ключей, для возможности проверки токена получающей стороной, без уведомления о проверке отправляющей стороны или любой третьей стороны и т.д. Ещё в таких случаях имеет смысл использовать время начала действия токена и наименьшее возможное время жизни токена. Полезная нагрузка токена зависит от назначения сервисов, цели применения токена и т.д.
Если используется не минимальное возможное время жизни токена и/или необходимо иметь возможность отзывать токены, то без реестра в том или ином виде не обойтись. Для таких задач существует jti (идентификатор токена), кстати особых рекомендаций по поводу данных этого поля тоже нет (об этом ниже). Т.е. сами токены хранить не нужно, нужно хранить только их идентификаторы. Важно, что jti не является обязательным полем для всех токенов, решение о его применении принимается для конкретного случая.
Реестр может быть тоже по разному реализован: это может быть Redis с открытым/закрытым доступом, централизованный сервис для проверки валидности токенов (не обязательно выдающий эти токены) или даже открытый, периодически обновляемый файл с перечислением идентификаторов отозванных или активных токенов (в таком случае принимающая сторона может сама проверить отозван ли токен, запросив свободно распространяемый файл с идентификаторами токенов, по принципу проверки подписи через публичные ключи). Очевидно имеет смысл вести реестр именно отозванных токенов (наименьший объём хранимых данных).
Можно например сделать отдельный сервис отозванных токенов с двумя точками входа: точкой отзыва токена и открытый, обновляемый файл с идентификаторами отозванных токенов или точкой проверки наличия в реестре идентификатора. При запросе на отзыв токена необходимо передать либо отзываемый токен, либо идентификатор отзываемого токена с какой-то подписью для авторизации операции отзыва (вот ещё один возможный пример использования JWT для отзыва других токенов JWT).
Если мы рассматриваем JWT относительно аутентификации пользователей, то без сессий нам вероятно не обойтись. В большинстве случаев аутентификация пользователей завязана на сессии и альтернатив нет. В таком случае можно действительно обойтись и без JWT, но это не значит, что использование JWT с сессиями является не верным использованием JWT.
В таком случае имеет смысл сохранять идентификатор такой сессии в поле jti (вспоминаем, что особых рекомендаций по этому полю нет), таким образом jti (а точнее sid) будет идентифицировать не конкретный токен, а скорее группу связанных токенов. Так же в такой реализации у нас уже будет иметься реест действительных токенов (фактически реестр сессий), причём этот реестр по объёму будет где-то по середине между реестром всех активных токенов и реестром отозванных токенов. Для отзыва всех токенов сессии достаточно будет обновить идентификатор сессии или пересоздать её в реесте.
Полезная нагрузка такого токена зависит опять от сферы применения, целей и т.д. Единственное и главное, полезная нагрузка не должна содержать чувствительных данных и желательно не должна содержать часто обновляемых данных (частота обновления выше частоты смены токенов).
В итоге "правильных" вариантов использования нет, есть только рекомендации. Каждый разработчик должен сам придумать правильный вариант использования JWT для своих целей, желательно опираясь на рекомендации.
Мои примеры тоже не претендуют на единственно верные. Действительно для некоторых случаев использование JWT не даёт никаких преимуществ, возможно просто увеличивает трафик. Однако это вопрос уменьшения объёма трафика или применения стандартизированного контейнера.
Хорошая "забота" о разработчиках и о пользователях, но с намеренным умалчиванием множества фактов.
Например, iOS далеко не единственная и не основная платформа на которой распространяется тот или иной софт. Не спорю что есть решения чисто залоченные на вендоре Apple (и в таком случае ваш аргумент вполне применим до поры до времени), но во всей массе софта это единичные случаи. А значит данный аргумент "используй наше решение и не заботься/не думай" рушится о другие платформы, у которых может быть аналогичное решение или такого решения может вовсе и не быть. В любом случае поддерживать зоопарк реализаций.
В результате имеем то, что многие компании реализуют своё платёжное решение или используют стороннее и независимое от платформы решение. Допустим они могут себе позволить и/или хотят сами управлять данными процессами.
Однако агрессивная политика Apple заставляет эти компании, уже вложившие не малую сумму в собственную платежнуые системы, использовать или даже так — приоритетно продвигать именно платёжную систему Apple пусть даже в рамках экосистемы Apple.
И вот тут привет всем судебным делам в отношении Google по факту продвижения собственных сервисов на первых позициях и аналогичным прецедентам в отношении Яндекса. Чем данная политика Apple отличается от политик Google и Яндекса? Ответ ни чем.
Во всех случаях это построение экосистемы и тесная интеграция различных процессов, однако как только компания становится достаточно крупной и начинает охватывать слишком много процессов — её нужно начинать контролировать и даже разделять. Причем это пойдёт всем на пользу, всё-таки если компания слишком много процессов охватывает, но является одним огромным монолитом, значит с организационной структурой этой компании уже что-то не так и явно есть где-то потери.
Важный момент, что время не стоит на месте и законодательные нормы устаревают. Таких прецедентов "гиперконкуренции" ранее ещё не бывало и не предвиделось, очевидно настало время пересмотра анти-монопольных политик и законодательств, что последние 5 лет активно и делается, пока начали с крупных и довольно очевидных компаний, но со временем всех так перепроверят.
Всё, что не запрещено — законно, так и данная "гиперконкуренция" пока ещё законна, однако уже имеет очень тонкую грань, перейдя которую легко станет не законной. И данная грань сейчас плавает, определяя своё положение.
Аргументы про обеспечение безопасности со стороны Apple не подходят т.к. "крышевание" тоже обеспечение своеобразной безопасности, однако не сказать что это вообще законно.
В данном случае Apple действительно уже заняла монопольное положение на рынке дистрибуции ПО на платформе iOS. В обход нельзя, ведь на платформу даже не допускаются сторонние магазины, а значит App Store — единственный источник дистрибуции на платформе iOS, что равно монополии.
Другой бы разговор был, если всё-таки по мимо App Store имелись другие магазины, пусть даже доступные только через App Store. В таком варианте Apple может до определённого времени сохранять приоритетную роль дистрибутора софта на iOS, организуя достаточную безопасность с защитой от "дурака" пользователей, хотя бы предупреждая при установке других магазинов о возможных последствиях и дополнительных отказах от ответственности и гарантиях со стороны Apple (формат не согласился — не установил).
В отношении конкурентной платформы Android были дела и по серьёзней, так почему практики и прецеденты с их конкурентом должны обойти Apple стороной?
Сразу про другие аргументы типа "Apple вложилась в платформу iOS", "А почему они кому-то что-то должны" и "Apple продвигала платформу" — мало создать платформу, надо её наполнить. И вот тут, если бы не сторонние разработчики, которые пока делают под их платформу софт, не было бы ни macOS, ни iOS как бы их не продвигала Apple — они бы просто не набрали пользовательскую базу ввиду малого функционала.
Опять таки мы говорим о компании у которой согласно последнему отчету лежит мертвым грузом (без применения) огромнейшая сумма денег, а значит прибыль у них многократно превышает затраты.
Осталось чуть-чуть. Объяснить это всё массам пользователей и убедить их строго следовать этому подходу.
Нет, ну если хочется ещё проще, поскорее и без объяснений всем массам, можно принудительно зашить в браузерах https-only или https с фолбеком на http.
А вообще эта проблема должна будет решиться с внедрением выше упомянутого HTTPSSVC DNS resource record. Если у домена есть данная запись, браузер строго следует правилам в ней и использует https соединения. Если такой записи нет, работает точно так же как сейчас (http-first).
Вы, наверное, не в курсе, но без HSTS preloaded list запрос сначала пойдет на 80-ый порт.
Если не указывать протокол браузер вероятнее всего будет использовать http и тогда да в начале пойдёт на 80-ый порт. А если ручками указать протокол https, будет использоваться только 443 порт (если вы и порт ручками не указали). Причём это весьма не сложно (всего дополнительно 8 символов и то если вспомнить, что слеши не обязательны — 6 символов, https:example.com).
Но вот это "вероятнее всего" зависит от множества факторов:
Для начала в "большой тройке" браузеров (Chromium, Firefox, Safari), HSTS preload list поставляется изначально далеко не пустой. Более того этот список с обновлениями браузеров подкачивается/синхронизируется. Кстати производитель вполне может в этот список на этапе поставки браузера добавить дополнительные записи.
Так же этот список локально обновляется сайтами с HSTS header и не значащимися в HSTS preload list — тут действительно первый заход будет на 80-ый порт, однако последующие уже на 443-ий.
Стоит отметить, что в выше указанный HSTS preload list жестко вшиты некоторые домены первого уровня (.dev, .app), а значит на сайты в этих gTLD браузеры заходят только на 443-ий порт, игнорируя вообще существование 80-го порта.
А вообще HSTS header де-факто уже признан устаревшим и ему на смену готовят HTTPSSVC DNS resource record. Это по сути замена сразу двух HTTP заголовков HSTS header и AltSvc header с интеграцией сюда ESNI.
В данной схеме устраняется та самая уязвимость первого захода с HSTS header. Главная идея в том, что браузер будет ходить на порты, указанные в DNS записи и по протоколам так же указанным в этой записи. Например, на ещё не посещённый сайт сразу на 443 порт так ещё по протоколу Quic или HTTP/3 и с применением ESNI.
Также рассматривается будущая (через 2-5+ лет) возможность признания протокола http устаревшим с дальнейшим выпиливанием из браузеров, по аналогии с протоколом ftp в этом году.
Ну почему же только компания, которой он продал права, а другая компания купившая эксклюзивные права на дистрибуцию, у первой компании. А компания представляющая первую или вторую компанию и выполняющая сборы от их имени. А может он продал права на одну и туже композицию нескольким компаниям (а те могут продать права на дистрибуцию). Ах да, ещё он мог продать права на текст одной компании, а права на конкретную версию (запись) другой компании. Или например, наоборот сохранить права на текст за собой, но продать именно конкретную версию исполнения (запись). Кстати именно оговорка про конкретную версию исполнения очень важна.
Так что в конечном итоге вполне может быть и какая-то довольно левая компания, с которой автор дел и не имел.
Всё очень сложно и зависит от условий передачи прав, а так же от того насколько расписаны законы.
А ещё можно и самому создавать из tar с командой wsl:
--import <Distro> <InstallLocation> <FileName> [Options]
Импорт указанного TAR-файла в качестве нового дистрибутива.
В качестве имени стандартного выходного файла можно указать "-".
Параметры:
--version <Version>
Указание версии, которую нужно использовать для нового дистрибутива.
Всерьёз так ни кто не делает, потому, что из всех браузеров отличились разработчики Safari, отказавшись реализовывать расширение нативных элементов. В Safari в целом наследование не от
HTMLElement
просто не работает.Семантика пользовательским элементам задаётся двумя способами:
role
,aria-label
и т.д. т.п. (Устанавливается либо через сеттерыrole
,ariaLabel
и т.д. Либо через установку атрибута);ElementInternals
.По семантике ещё делается "виртуальное дерево" для использования с
canvas
и д.р.Это правда. Просто получилось, что те кто понимают суть JAM хотя бы частично, горят что пример только часть JAM'а, а те кто не в теме получили либо не полное, либо ложное понимание. Автор оригинальной статьи тоже "молодец" с его "Нет" серверам, и в середине "Да" серверам.
Автор сам запутался во всех "новых" словах которые он узнал за последние пару лет.
Сам JAMstack далеко не новый, название и реклама да, подход нет. И он не умирал и не умирает, а живёт и процветает, подстраиваясь под 5 лет эволюции веба (на самом деле 10 лет, а если честнее ещё больше). Ключевые JAM: JavaScript API Markup никуда не пропадали.
SPA тоже JAMstack, т.к. есть JavaScript, есть API и есть Markup (пусть и в виде одной страницы).
С сайта JAMstack.wtf:
JAMstack не противоречит SPA, а даже наоборот. Главный манифест JAM — JavaScript API Markup, а это всё есть почти в любом SPA (есть SPA не использующие API серверов).
На самом деле всё зависит от подхода, можно каждый раз генерировать полностью целый сайт, а можно перегенерировать только изменившиеся страницы (Incremental Build). Это конечно ещё и от инструментов зависит.
Вообще стоит сказать, что JAMstack может быть и без генераторов на самом деле. Если у вас собранная руками html страничка и есть как клиентский JavaScript, так и запросы к API — вы уже используете JAMstack. Даже если страница фактически будет тупо скелетоном это всё ещё JAMstack, хотя больше продвигается "прогрессивный" подход. Тут важно ещё не забывать про клиентскую сторону — мегабайты кода. Всё это всё ещё нужно оптимизировать.
А вот это в рамочку. В зависимости от подхода к JAMstack вы будете платить временем и объёмом хранилища.
Но ведь у вас всё равно в итоге получился не JAMstack. Вы всё ещё используете чисто второй подход скатываясь к первому, только рендер перенесли с on-prem на этап сборки. В итоге на выходе у вас только статическая разметка (пусть и сгенерированная). Это путь всевозможных статических генераторов и только часть JAMstack, даже не половина, а скорее треть.
Чтобы получился действительно настоящий JAMstack нужно скрестить все 3 варианта. Причём даже в статье расшифровка приведена JavaScript API Markup. Т.е. к вашему варианту нужно ещё добавить сервер с API (и вот оно расхождение в статье) и клиентский JavaScript код, тогда у вас будет действительно JAMstack.
Фактически сайты на React/Vue/etc, если используют API, гидрацию и будут собирать страницы в статику именно на этапе сборки — настоящий JAMstack.
Чтобы понять что такое JAMstack, оставлю ссылку на JAMstack.wtf. А вообще всё это довольно олдскульно, даже JAMstack существует далеко не 4 года и не 8.
Вот в этом мы разошлись, я под словом "чувствительные" понимал данные, попадание которых в открытый доступ является проблемой безопасности в том или ином виде. Ровно так же про чувствительность данных в полезной нагрузке трактуется в стандарте, там есть ремарка по поводу использования JWE для этих целей.
Тут вопрос скорее такой, что считать правильным, а что не правильным. JWT даёт возможность самому исполнять для конкретной задачи конкретный вариант реализации. Причём иногда этот вариант со стороны может выглядеть как "дико неправильный", но это со стороны и смотря только на верхушку айсберга, что внизу вы явно не знаете.
В конце концов то, что сейчас считается не правильным, через несколько лет может оказаться верным.
Опять таки если мы рассматриваем алгоритмы подписи JWT, среди которых есть hash-only HS* (SHA*) и специальный "none" у которых просто нет пар ключей, аргумент про длину подписи зависящую от длины ключа точно так же опровергается. Подчёркиваю я настаиваю именно на утверждении, что подпись JWT зависит от выбранного алгоритма подписи JWT, если это "none" — длина подписи будет равна 0, если это HS* — будет равна размеру хэш-блока, если это RS*, ES*, PS* будет зависеть от длины ключа т.к. длина результата алгоритмов RSA, ECDSA будет зависеть от длины ключа. Но последнее утверждение не применимо к алгоритмам HS* и "none", именно по этому я настаиваю на связи именно от алгоритма подписи JWT. Не стоит откидывать алгоритмы HS* и "none" для них найдутся применения.
И даже при использовании любой пары RS* (RSA) — RS256 и RS512? Это же именно алгоритмы генерации подписи JWT, различия между ними в алгоритмах генерации хешей SHA256 и SHA512, но одинаковый алгоритм RSA. Ладно длина будет одна, но ключи можно использовать одинаковые как для RS256, так и для RS512. И опять таки это не противоречит тому, что я пишу — длина подписи JWT зависит именно от алгоритма подписи JWT, алгоритм подписи JWT может работать как с ключами RS*, ES*, PS*, так и без ключей HS* и "none". Если использовать разные ключи одинаковой длинны в разных алгоритмах с одинаковой хеш-функцией (например SHA256) длина подписи будет разная и зависеть от самого алгоритма будь то RSA или ECDSA.
И всё-таки не зависит от ключа на прямую, но зависит от алгоритма подписи напрямую.
Я именно об этом, ведь если мы используем не пары ключей, а просто секретную строчку и один из алгоритмов HS* — длина подписи будет зависеть только от выбранного алгоритма, но ни как не от длины секретной строчки. Т.к. тут у нас только хеш.
Если мы используем уже пары ключей, тут уже сами алгоритмы зависят от длины ключей согласен. Но сама подпись опять таки в глобальном смысле зависит именно от алгоритма подписи. Ведь даже если мы будем использовать одинаковые ключи (очевидно с одинаковой длинной), но разные алгоритмы (мы же можем использовать как RS512, так и RS256 с одной и той же парой ключей), то длинна подписи будет разной вне зависимости от одинаковой длинны ключей т.к. величина блоков этих алгоритмов разная.
Мы же ведём речь о стандарте JWT в целом, а он поддерживает множество алгоритмов подписей в т.ч. и не на ключах. Если выбрать указанный алгоритм "none", то подпись будет равна длине 0 (т.е. вовсе отсутствовать).
Дело в том, что неправильных тоже нет.
В конце своего сообщения я указал пример выбора решения использования JWT не смотря на то, что он увеличивает объём трафика и может показаться более жирным чем тупо id + подпись. Главный аргумент — стандартизованный контейнер, об этом даже в самом стандарте написано. JWT это платформо-независимый контейнер токенов, со статусом стандарта. В base64 все вполне умеют в криптографические подписи тоже и в JSON тоже. Его сделали, специально таким гибким и универсальным ведь в большинстве случаев разработка своего формата токенов является задачей сложной, мало сформулировать формат, нужно его внедрить и поддерживать.
Если речь идёт о ваших внутренних сервисах, которые разрабатываете вы лично или небольшая команда, очевидно id + подпись вам будет использовать выгоднее (правда не всегда). Но если речь заходит о том, что это экосистема разрабатываемая огромным количеством независимых людей и взаимодействие не ограничивается только лишь вашими сервисами, то JWT тут побеждает как минимум имея статус стандарта, гибкостью и уже имеющейся интеграцией и поддержкой.
Потом, в моём примере про хранение сессионного id в jti я не писал, что в токене должен храниться только jti, вы можете вполне туда добавить не чувствительные данные (настоятельно подчёркиваю, что не чувствительные данные) пользователя (например логин, аватар, возможно имя и т.д.), в том числе чтобы снизить нагрузку на базу (это к слову является одним из примеров использования в самом стандарте).
Вот с этим поспорю и очень даже сильно. Чувствительные данные в токене вы можете хранить, если используете специальную версию JWE с шифрование, но не JWT. JWT является открытым форматом и именно по этому в полезной нагрузке подчёркнуто нельзя хранить чувствительные данные. Отзыв токена не влияет на доступ к этим данным. Они опубликованы открытым текстом (если не учитывать b64). И этот токен может сохраняться где угодно и сколько угодно и вы даже не будете об этом знать. Данные в нём соответственно тоже. Именно по этому в JWT должны храниться только не чувствительные данные.
Не во всех сферах и реализациях это необходимо, опять таки мой пример варианта реализации сервиса отзывов JWT. Я там упомянул про использование JWT для отзыва других JWT.
А мысль следующая в JWT в поле субъекта указываете id отзываемого токена, время жизни создаваемого токена для авторизации отзыва минимальна, но достаточна на совершение операции. Подпись такого токена производится закрытым ключём клиента, имеющего возможность отзывать токены. Публичный ключ клиента сервису отзывов так или иначе известен. Подпись в данном случае совместно с идентификатором клиента (в поле полезной нагрузки) являются аутентификационными данными клиента, запрашивающего отзыв токена. Причём в авторизационном токене хранить jti не нужно, его просто на просто не нужно отзывать. Сама операция отзыва может быть произведена явно только один раз, т.к. на последующие запросы с этим токеном мы можем ничего не делать (в реестре уже будет идентификатор отзываемого токена). Тут уже помогает время жизни авторизационного токена, можно ещё в нём указать время жизни отзываемого токена.
Обращаю внимание реализация зависит от нужд, ни что не является обязательным, если в стандарте явно не указано об этом и не аргументировано.
Скорее зависит от применяемого алгоритма подписи. Подпись ведь является по своей сути хешем.
Мне кажется в стандарте явно не указаны примеры "правильных" использований JWT т.к. это своего рода просто стандартизированный контейнер. А сама реализация, набор данных и т.д. — является инженерной задачей, относящейся к конкретной сфере применения. Есть разные задачи с разными подходами применения JWT и наборами данных.
Например, если речь идёт о коммуникации machine-to-machine (по своей сути микро-сервисы), очевидно, что JWT должны работать на парах ключей, для возможности проверки токена получающей стороной, без уведомления о проверке отправляющей стороны или любой третьей стороны и т.д. Ещё в таких случаях имеет смысл использовать время начала действия токена и наименьшее возможное время жизни токена. Полезная нагрузка токена зависит от назначения сервисов, цели применения токена и т.д.
Если используется не минимальное возможное время жизни токена и/или необходимо иметь возможность отзывать токены, то без реестра в том или ином виде не обойтись. Для таких задач существует jti (идентификатор токена), кстати особых рекомендаций по поводу данных этого поля тоже нет (об этом ниже). Т.е. сами токены хранить не нужно, нужно хранить только их идентификаторы. Важно, что jti не является обязательным полем для всех токенов, решение о его применении принимается для конкретного случая.
Реестр может быть тоже по разному реализован: это может быть Redis с открытым/закрытым доступом, централизованный сервис для проверки валидности токенов (не обязательно выдающий эти токены) или даже открытый, периодически обновляемый файл с перечислением идентификаторов отозванных или активных токенов (в таком случае принимающая сторона может сама проверить отозван ли токен, запросив свободно распространяемый файл с идентификаторами токенов, по принципу проверки подписи через публичные ключи). Очевидно имеет смысл вести реестр именно отозванных токенов (наименьший объём хранимых данных).
Можно например сделать отдельный сервис отозванных токенов с двумя точками входа: точкой отзыва токена и открытый, обновляемый файл с идентификаторами отозванных токенов или точкой проверки наличия в реестре идентификатора. При запросе на отзыв токена необходимо передать либо отзываемый токен, либо идентификатор отзываемого токена с какой-то подписью для авторизации операции отзыва (вот ещё один возможный пример использования JWT для отзыва других токенов JWT).
Если мы рассматриваем JWT относительно аутентификации пользователей, то без сессий нам вероятно не обойтись. В большинстве случаев аутентификация пользователей завязана на сессии и альтернатив нет. В таком случае можно действительно обойтись и без JWT, но это не значит, что использование JWT с сессиями является не верным использованием JWT.
В таком случае имеет смысл сохранять идентификатор такой сессии в поле jti (вспоминаем, что особых рекомендаций по этому полю нет), таким образом jti (а точнее sid) будет идентифицировать не конкретный токен, а скорее группу связанных токенов. Так же в такой реализации у нас уже будет иметься реест действительных токенов (фактически реестр сессий), причём этот реестр по объёму будет где-то по середине между реестром всех активных токенов и реестром отозванных токенов. Для отзыва всех токенов сессии достаточно будет обновить идентификатор сессии или пересоздать её в реесте.
Полезная нагрузка такого токена зависит опять от сферы применения, целей и т.д. Единственное и главное, полезная нагрузка не должна содержать чувствительных данных и желательно не должна содержать часто обновляемых данных (частота обновления выше частоты смены токенов).
В итоге "правильных" вариантов использования нет, есть только рекомендации. Каждый разработчик должен сам придумать правильный вариант использования JWT для своих целей, желательно опираясь на рекомендации.
Мои примеры тоже не претендуют на единственно верные. Действительно для некоторых случаев использование JWT не даёт никаких преимуществ, возможно просто увеличивает трафик. Однако это вопрос уменьшения объёма трафика или применения стандартизированного контейнера.
Хорошая "забота" о разработчиках и о пользователях, но с намеренным умалчиванием множества фактов.
Например, iOS далеко не единственная и не основная платформа на которой распространяется тот или иной софт. Не спорю что есть решения чисто залоченные на вендоре Apple (и в таком случае ваш аргумент вполне применим до поры до времени), но во всей массе софта это единичные случаи. А значит данный аргумент "используй наше решение и не заботься/не думай" рушится о другие платформы, у которых может быть аналогичное решение или такого решения может вовсе и не быть. В любом случае поддерживать зоопарк реализаций.
В результате имеем то, что многие компании реализуют своё платёжное решение или используют стороннее и независимое от платформы решение. Допустим они могут себе позволить и/или хотят сами управлять данными процессами.
Однако агрессивная политика Apple заставляет эти компании, уже вложившие не малую сумму в собственную платежнуые системы, использовать или даже так — приоритетно продвигать именно платёжную систему Apple пусть даже в рамках экосистемы Apple.
И вот тут привет всем судебным делам в отношении Google по факту продвижения собственных сервисов на первых позициях и аналогичным прецедентам в отношении Яндекса. Чем данная политика Apple отличается от политик Google и Яндекса? Ответ ни чем.
Во всех случаях это построение экосистемы и тесная интеграция различных процессов, однако как только компания становится достаточно крупной и начинает охватывать слишком много процессов — её нужно начинать контролировать и даже разделять. Причем это пойдёт всем на пользу, всё-таки если компания слишком много процессов охватывает, но является одним огромным монолитом, значит с организационной структурой этой компании уже что-то не так и явно есть где-то потери.
Важный момент, что время не стоит на месте и законодательные нормы устаревают. Таких прецедентов "гиперконкуренции" ранее ещё не бывало и не предвиделось, очевидно настало время пересмотра анти-монопольных политик и законодательств, что последние 5 лет активно и делается, пока начали с крупных и довольно очевидных компаний, но со временем всех так перепроверят.
Всё, что не запрещено — законно, так и данная "гиперконкуренция" пока ещё законна, однако уже имеет очень тонкую грань, перейдя которую легко станет не законной. И данная грань сейчас плавает, определяя своё положение.
Аргументы про обеспечение безопасности со стороны Apple не подходят т.к. "крышевание" тоже обеспечение своеобразной безопасности, однако не сказать что это вообще законно.
В данном случае Apple действительно уже заняла монопольное положение на рынке дистрибуции ПО на платформе iOS. В обход нельзя, ведь на платформу даже не допускаются сторонние магазины, а значит App Store — единственный источник дистрибуции на платформе iOS, что равно монополии.
Другой бы разговор был, если всё-таки по мимо App Store имелись другие магазины, пусть даже доступные только через App Store. В таком варианте Apple может до определённого времени сохранять приоритетную роль дистрибутора софта на iOS, организуя достаточную безопасность с защитой
от "дурака"пользователей, хотя бы предупреждая при установке других магазинов о возможных последствиях и дополнительных отказах от ответственности и гарантиях со стороны Apple (формат не согласился — не установил).В отношении конкурентной платформы Android были дела и по серьёзней, так почему практики и прецеденты с их конкурентом должны обойти Apple стороной?
Сразу про другие аргументы типа "Apple вложилась в платформу iOS", "А почему они кому-то что-то должны" и "Apple продвигала платформу" — мало создать платформу, надо её наполнить. И вот тут, если бы не сторонние разработчики, которые пока делают под их платформу софт, не было бы ни macOS, ни iOS как бы их не продвигала Apple — они бы просто не набрали пользовательскую базу ввиду малого функционала.
Опять таки мы говорим о компании у которой согласно последнему отчету лежит мертвым грузом (без применения) огромнейшая сумма денег, а значит прибыль у них многократно превышает затраты.
В общем всё очень многогранно и не так очевидно.
Нет, ну если хочется ещё проще, поскорее и без объяснений всем массам, можно принудительно зашить в браузерах https-only или https с фолбеком на http.
А вообще эта проблема должна будет решиться с внедрением выше упомянутого HTTPSSVC DNS resource record. Если у домена есть данная запись, браузер строго следует правилам в ней и использует https соединения. Если такой записи нет, работает точно так же как сейчас (http-first).
Если не указывать протокол браузер вероятнее всего будет использовать http и тогда да в начале пойдёт на 80-ый порт. А если ручками указать протокол https, будет использоваться только 443 порт (если вы и порт ручками не указали). Причём это весьма не сложно (всего дополнительно 8 символов и то если вспомнить, что слеши не обязательны — 6 символов, https:example.com).
Но вот это "вероятнее всего" зависит от множества факторов:
Для начала в "большой тройке" браузеров (Chromium, Firefox, Safari), HSTS preload list поставляется изначально далеко не пустой. Более того этот список с обновлениями браузеров подкачивается/синхронизируется. Кстати производитель вполне может в этот список на этапе поставки браузера добавить дополнительные записи.
Так же этот список локально обновляется сайтами с HSTS header и не значащимися в HSTS preload list — тут действительно первый заход будет на 80-ый порт, однако последующие уже на 443-ий.
Стоит отметить, что в выше указанный HSTS preload list жестко вшиты некоторые домены первого уровня (.dev, .app), а значит на сайты в этих gTLD браузеры заходят только на 443-ий порт, игнорируя вообще существование 80-го порта.
А вообще HSTS header де-факто уже признан устаревшим и ему на смену готовят HTTPSSVC DNS resource record. Это по сути замена сразу двух HTTP заголовков HSTS header и AltSvc header с интеграцией сюда ESNI.
В данной схеме устраняется та самая уязвимость первого захода с HSTS header. Главная идея в том, что браузер будет ходить на порты, указанные в DNS записи и по протоколам так же указанным в этой записи. Например, на ещё не посещённый сайт сразу на 443 порт так ещё по протоколу Quic или HTTP/3 и с применением ESNI.
Также рассматривается будущая (через 2-5+ лет) возможность признания протокола http устаревшим с дальнейшим выпиливанием из браузеров, по аналогии с протоколом ftp в этом году.
Ну почему же только компания, которой он продал права, а другая компания купившая эксклюзивные права на дистрибуцию, у первой компании. А компания представляющая первую или вторую компанию и выполняющая сборы от их имени. А может он продал права на одну и туже композицию нескольким компаниям (а те могут продать права на дистрибуцию). Ах да, ещё он мог продать права на текст одной компании, а права на конкретную версию (запись) другой компании. Или например, наоборот сохранить права на текст за собой, но продать именно конкретную версию исполнения (запись). Кстати именно оговорка про конкретную версию исполнения очень важна.
Так что в конечном итоге вполне может быть и какая-то довольно левая компания, с которой автор дел и не имел.
Всё очень сложно и зависит от условий передачи прав, а так же от того насколько расписаны законы.
Это должно будет придти с версией Windows 10 Pro
2004
(Пока Insider Preview), а сейчас доступно как сетевая папка\\wsl$
.Почему же, вот открыл Microsoft Store и что я вижу:
Раньше ешё были Fedora официальные, но сейчас их нет.
Остальные/Кастомы:
А ещё можно и самому создавать из tar с командой
wsl
: