пїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅ
По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие
наши статьи:
Стандарт JSON Web Tokens (JWT) – это лаконичный метод передачи данных, поддающихся проверке. Каждый токен содержит подпись, с помощью которой эмитент может проверить целостность сообщения.
С помощью этой статьи вы можете узнать, что из себя представляет структура JWT и как можно создать свои собственные токены. JWT – это популярный способ защиты API и аутентификации сеансов пользователей, так как они достаточно просты и являются автономными.
Как работают JWT?
Одна из самых распространенных задач в любом API – это проверка того факта, что пользователи являются теми, за кого себя выдают. Как правило, аутентификация выполняется тогда, когда клиент использует ключ API для запросов, которые он отправляет на сервер. Этот ключ содержит информацию, которая подтверждает личность пользователя. Но все еще остается вопрос: как сервер проверяет, что пользователь сначала предоставил ключ?
JWT с легкостью решают эту проблему с помощью секретного ключа, который используется для подписи каждого токена. Сервер проверяет действительность токена, повторно пересчитывая подпись с помощью своего секретного ключа. Любое несанкционированное вмешательство приведет к тому, что проверка не будет выполнена.
Структура JWT
JWT состоят из трех отдельных компонентов:
Заголовок
(header) – содержит метаданные о токене, например, алгоритм подписи, который был использован.
Полезная нагрузка
(payload) – в качестве полезной нагрузки могут выступать любые случайные данные, которые так или иначе относятся к вашей системе. Полезная нагрузка может содержать ID пользователя и набор определенных функций, с которыми пользователь может взаимодействовать.
Подпись
(signature) – подпись позволяет в дальнейшем проверить целостность токена. Подпись создается путем подписания заголовка и полезной нагрузки с помощью секретного ключа, который знает только сервер.
Для того, чтобы сформировать JWT, все эти три компонента нужно записать через точку:
header.payload.signature
Каждый компонент кодируется с помощью стандарта Base-64. Готовый токен представляет собой строку текста, которую можно использовать в средах разработки программ и отправлять вместе с HTTP-запросами.
Создание JWT
Создать JWT можно на любом языке программирования. В данном случае мы будем использовать PHP, но вы можете использовать и другой язык, процесс будет аналогичным.
Начнем с создания заголовка. Как правило, он включает в себя два поля –
alg
и
typ
:
alg
– это алгоритм хеширования, который мы будем использовать для создания подписи. Как правило, используют HMAC SHA256 (
HS256
).
typ
– это тип токена, который мы создаем. Здесь мы должны указать
JWT
.
Вот так выглядит объект JSON, который определяет заголовок:
{
"alg": "HS256",
"typ": "JWT"
}
Заголовок необходимо закодировать с помощью Base-64:
$headerData = ["alg" => "HS256", "typ" => "JWT"];
$header = base64_encode(json_encode($headerData));
Затем нам необходимо определить еще один объект JSON - полезную нагрузку токена. Что из себя будет представлять полезная нагрузка зависит от приложения. В данном примере мы используем информацию об учетной записи аутентифицированного пользователя и информацию о самом токене.
exp
,
iat
и
nbf
– это условные поля, которые используются для того, чтобы указать время истечения срока действия токена, время его создания и момент времени (начальный), до которого он считается недействительным. Полезную нагрузку также необходимо закодировать с помощью Base-64.
$payloadData = [
"userId" => 1001,
"userName" => "demo",
"licensedFeatures" => ["todos", "calendar", "invoicing"],
"exp" => (time() + 900),
"iat" => time(),
"nbf" => time()
];
$payload = base64_encode(json_encode($payloadData));
Нам остается только создать подпись. Для этого сначала нужно объединить заголовок и полезную нагрузку в одну сроку, разделив их точкой:
$headerAndPayload = "$header.$payload";
Затем мы должны сгенерировать уникальный секретный ключ, который мы будем использовать в качестве секретного ключа подписи. Этот ключ должен надежно храниться на вашем сервере, и его ни в коем случае нельзя передавать клиентам. Если значение секретного ключа будет раскрыто, то любой пользователь сможет создавать действительные токены.
// PHP method to generate 32 random characters
$secret = bin2hex(openssl_random_pseudo_bytes(16));
И мы завершаем процесс с помощью подписи объединенной строки (заголовка и полезной нагрузки) с помощью секретного ключа. Для этого мы будем использовать алгоритм хеширования, который мы указали в заголовке. Получившаяся подпись также, как и другие компоненты, должна быть закодирована с помощью Base-64.
$signature = base64_encode(hash_hmac("sha256", $headerAndPayload, $secret, true));
Итак, у нас теперь есть заголовок, полезная нагрузка и подпись. Они представляют собой отдельные текстовые компоненты. Для того, чтобы создать JWT, мы должны объединить из с помощью точки. И теперь мы можем отправить его клиенту:
$jwt = "$header.$payload.$signature";
Проверка входящих JWT
Клиентское приложение может определить, какие функции доступны пользователю, если расшифрует полезную нагрузку токена. Вот пример, написанный на JavaScript:
const tokenComponents = jwt.split(".");
const payload = token[1];
const payloadDecoded = JSON.parse(atob(payload));
// ["todos", "calendar", "invoicing"]
console.log(payloadDecoded.licensedFeatures);
Злоумышленник может подумать, что эти данные представляют собой простой текст и его легко изменить. Он может попробовать убедить сервер в том, что у него есть некая дополнительная доступная ему функция, изменив полезную нагрузку токена в своем запросе:
// Create a new payload component
const modifiedPayload = btoa(JSON.stringify({
...payloadDecoded,
licensedFeatures: ["todos", "calendar", "invoicing", "extraPremiumFeature"]
}));
// Stitch the JWT back together with the original header and signature
const newJwt = `${token[0]}.${modifiedPayload}.${token[2]}`
Как же сервер защищается от подобных атак? Ответ заключается в процессе создания подписи. Значение подписи учитывает, как заголовок токена, так и его полезную нагрузку. В случае данного примера изменение полезной нагрузки ведет к тому, что подпись становится недействительной.
Серверная программа проверяет входящие JWT путем пересчета их подписей. Если подпись, отправленная клиентом, не совпадает с подписью, посчитанной на сервере, то можно сделать вывод о том, что токен был подделан.
$tamperedToken = $_POST["apiKey"];
list($header, $payload, $signature) = $tamperedToken;
// Determine the signature this token *should* have
// when the server's secret is used as the key
$expectedSignature = hash_hmac("sha256", "$header.$payload", $secret, true);
// The token has been tampered with because its
// signature is incorrect for the data it includes
if ($signature !== $expectedSignature) {
http_response_code(403);
}
// The signatures match - we generated this
// token and can safely trust its data
else {
$user = fetchUserById($payload["userId"]);
}
Злоумышленник не может создать действительный токен, если он не знает секретный ключ, который хранится на сервере. Также это означает, что случайная утеря или преднамеренная передача секретного ключа сразу же делает все ранее созданные токены недействительными.
В реальной ситуации ваш код аутентификации должен проверять срок действия токена, а также должен убедиться, что он уже является действительным (
nbf
в полезной нагрузке). Это все необходимо для того, чтобы определить, является ли сеанс пользователя действительным.
Когда нужно использовать JWT
JWT, как правило используют для аутентификации API, поскольку их достаточно просто реализовать на сервере, легко использовать на клиентской стороне и просто передавать через границы сети. Но несмотря на то, что они такие простые, они обеспечивают хороший уровень безопасности за счет того, что каждый токен подписывается с помощью секретного ключа, который хранится на сервере.
JWT – это механизм, который не фиксирует текущее состояние, поэтому нет необходимости фиксировать информацию о созданных токенах на вашем сервере. Информацию о клиенте, который предоставляет вам JWT, вы можете получить из полезной нагрузки, а не искать ее в базе данных. После того, как подпись будет проверена, эта информация будет считаться достоверной.
Если вам необходимо обмениваться информацией между двумя сторонами без какого-либо постороннего вмешательства, то использование JWT – это отличный вариант. Однако у этого механизма есть слабые места, о которых следует знать заранее. В случае, если произойдет утечка секретного ключа или если ваш код проверки подписи содержит ошибку, то будет скомпрометирована вся система. Именно поэтому для реализации процесса создания и проверки JWT многие разработчики используют библиотеку с открытым исходным кодом. Функции доступны для всех популярных языков программирования, и они исключают риск ошибок при проверке токена.
Заключение
Стандарт JWT – это формат обмена данными, который включает в себя проверку целостности. Как правило, JWT используют для защиты взаимодействия между серверами API и клиентскими приложениями. Сервер может доверять входящим токенам, если у него получается воспроизвести их подписи. С помощью информации, полученной из полезной нагрузки, можно обеспечить безопасность при выполнении каких-либо действий
JWT достаточно удобны, но при этом имеют некоторые недостатки. Текстовое представление JWT в кодировке Base-64 может быть слишком объемным, если в полезной нагрузке будет слишком много полей. Это будет недопустимым потреблением ресурсов, если ваш клиент собирается отправлять JWT с каждым запросом.
Еще одним возможным недостатком может оказаться то, что JWT не фиксирует текущее состояние. После того, как токен был создан, он является неизменяемым и должен использоваться как есть до истечения своего срока действия. Клиенты, которые используют полезные данные JWT для определения прав доступа пользователя или для использования лицензированных функций, должны будут получать новый токен с сервера каждый раз, когда что-то из этого меняется.
Ошибаться полезно, особенно на начальном этапе проекта, а сделать все идеально получается редко с первого раза. Можно даже выполнять эту работу профессионально — искать ошибки, тестировать ПО и получать за это деньги. Этим занимаются тестировщики, а отчет об ошибках называется баг-репорт. Отчеты об ошибках — неотъемлемая часть тестирования программного обеспечения, поскольку они помогают выявлять и фиксировать любые проблемы, возникающие в процессе работы. Используя отчет об ошибках, тестировщики могут отслеживать ход своей работы и сравнивать результаты проекта. Давайте разберемся подробнее, что такое баг-репорт, как он оформляется, какие бывают виды баг-репортов и как составить эффективный отчет об ошибках.
Что такое баг-репорт
Баг-репорт — это документ, в котором тестировщик описывает найденный дефект в программе. Он играет важную роль в процессе разработки ПО, помогая командам быстро и эффективно исправлять ошибки. Правильно составленный баг-репорт улучшает качество проекта. Обычно он включает в себя шаги, необходимые для воспроизведения проблемы, ожидаемый и наблюдаемый результат. Основная цель сообщения об ошибке — предоставить команде разработчиков точное описание проблемы, чтобы облегчить ее решение. Отчеты об ошибках должны быть четкими, краткими и корректными, чтобы помочь разработчикам быстро вникнуть в суть.
Все баги заносятся в систему отчетов об ошибках, чтобы в будущем их можно было оперативно выявить, определить приоритет, назначить ответственного и устранить. В противном случае разработчик может не понять или проигнорировать проблему, не осознать ее серьезность и оставить ошибку в коде.
Преимущества четко составленного баг-репорта
Он поможет вам точно определить, что именно не так с ошибкой, и найти оптимальный способ ее устранения.
Сэкономит время и деньги, помогая поймать ошибку до того, как она повлечет за собой последствия.
Не дает ошибкам попасть в конечный продукт и испортить всю работу.
Поможет избежать повторного появления той же ошибки в будущих версиях.
Благодаря понятному баг-репорту все участники процесса будут знать, что происходит с ошибкой, и смогут принять меры.
Какая информация должна быть в отчете об ошибках
Заголовок.
В него входит краткое описание проблемы, плюс каждой ошибке может быть присвоен уникальный идентификационный номер (ID). Эти данные помогают легко идентифицировать ошибку.
Описание.
Даем подробное описание ошибки, что происходит и при каких условиях. Описание должно быть составлено простым языком, который разработчик сможет легко понять. Необходимо указать все подробности об ошибке.
Шаги воспроизведения.
Инструкции, которые позволят разработчику воспроизвести ошибку. Здесь надо подробно описать шаги, предпринятые для воспроизведения проблемы. Так разработчик получит необходимую информацию для выявления и решения проблемы. Тестовые шаги должны быть написаны четко и лаконично, подробно описывая каждое действие, чтобы разработчик мог легко следовать им.
Ожидаемый результат.
Распишите, что должно было получиться, если бы ошибки не было. Этот раздел также будет полезен при повторном тестировании ошибки.
Фактический результат.
Рубрика «ожидание/реальность». Фиксируем,
что происходит на самом деле, когда ошибка появляется, указываем фактический результат выполнения тестовых шагов. Независимо от результата, документирование того, что произошло, поможет улучшить будущие сценарии.
Репортер
. То есть тестировщик, нашедший ошибку. Указываем имя и электронную почту автора, это поможет разработчику быстро определить, кто сообщил об ошибке и связаться с автором сообщения, если требуется обсудить ошибку.
Дата сообщения
. Необходимо указать дату, когда ошибка была обнаружена. Это поможет определить релиз, в котором произошла ошибка.
Ответственный.
Ошибка может быть закреплена за владельцем продукта или менеджером по разработке. В некоторых случаях можно не назначать ответственного, а добавить задачи в очередь ошибок, где разработчики смогут выбрать их в соответствии с приоритетом.
Приоритет
. Обычно определяется тестировщиком или владельцем продукта с учетом серьезности ошибки, времени и доступных ресурсов. Опишите, как ошибка влияет на функциональность программного обеспечения, и определите степень ее срочности. Можно разбить на несколько категорий:
— Критический:
Ошибки, критически важные для основной функциональности приложения, без обходных путей.
— Срочный:
Ошибки, связанные с основной функциональностью приложения, которые необходимо срочно исправить в течение спринта.
— Высокий:
Ошибки, не влияющие на функциональность проекта и имеющие обходные пути. Эти ошибки можно исправить в следующем спринте.
— Нормальный:
Ошибки, не мешающие основному функционалу, которые могут быть исправлены или оставлены.
— Низкий:
Ошибки с низким приоритетом, которые могут быть оставлены в бэклоге и закрыты как известные проблемы.
Скриншоты или видео.
Сюда подходят любые визуальные доказательства ошибки. На скриншоте можно выделить проблему, это поможет разработчику быстрее разобраться.
Информация об окружении.
Соберите данные о среде, такие как тип браузера, операционная система и версии применимого программного обеспечения.
Логи и трассировки.
Внестие лог-файлы или трассировки, которые могут помочь в диагностике проблемы.
Несколько советов по составлению отчета
Хороший отчет об ошибке должен позволить разработчику и руководству понять суть проблемы. При работе учитывайте следующие рекомендации:
1. В сообщении об ошибке должна быть представлена вся необходимая информация. Будьте краткими и четкими. Постарайтесь изложить суть проблемы в нескольких предложениях, кратко, но исчерпывающе. Избегайте пространных описаний проблемы. Вместо этого придерживайтесь сути, чтобы оставаться лаконичными.
2. Сообщайте об ошибках как можно раньше. Важно сообщить об ошибке сразу же, как только вы ее обнаружили. Чем раньше вы уведомите команду о проблеме, тем быстрее команда сможет взять ее в работу и выпустить продукт.
3. Избегайте дублирования ошибок. Фиксируя ошибку, необходимо убедиться, что она не дублирует уже имеющуюся. Также проверьте список известных и открытых проблем. Сообщение о дублирующих ошибках может стоить разработчикам дополнительных усилий, что негативно скажется на жизненном цикле тестирования.
4. Создавайте отдельные баги для несвязанных проблем. Например, если в одной ошибке сообщается о нескольких проблемах, она не может быть закрыта, пока не будет исправлено все. Поэтому следует создавать отдельные баги, если проблемы не связаны друг с другом.
5. Не используйте авторитетный тон. При документировании ошибки избегайте командного тона, грубых слов или шуток над разработчиком. Цель хорошего отчета об ошибке - помочь разработчику понять ошибку и ее влияние на систему. Чем точнее и подробнее будет отчет об ошибке, тем быстрее и эффективнее она будет устранена.
Давайте еще разок, коротко: шаги по составлению баг-репорта
Воспроизведите ошибку последовательно.
Соберите данные о среде (тип браузера, ОС и т.д.).
Составьте четкие инструкции по воспроизведению ошибки.
Включите скриншоты или видео.
Опишите ожидаемый результат и чем он отличается от реального.
Укажите степень серьезности и приоритетности ошибки.
Проверьте наличие дубликатов.
Назначьте ошибку соответствующему разработчику или команде.
Следите за ходом работы над ошибкой.
Тестировщики должны составлять полные отчеты об ошибках для их анализа и устранения. Включение всей необходимой информации и четкое общение с разработчиками и менеджерами улучшает качество отчетов, ускоряет процесс и снижает затраты на исправление ошибок. Хорошие баг-репорты способствуют позитивному сотрудничеству между командами и снижают затраты на исправление ошибок.
Edge computing (дословно можно перевести как "граничные вычисления") - это сетевая философия, основанная на том, что вычисления должны совершаться как можно ближе к источнику сырых данных. Цель сего действа в сильном сокращении задержек и ширины канала связи. Если говорить проще, то edge computing - это когда меньше всякой всячины вычисляется к облаке или ЦОДе, и больше вычисляется непосредственно на месте - то есть на локальном ПК, IoT устройстве или на граничном сервере. Таким образом сокращается необходимость поддерживать в требуемом состоянии дорогостоящие каналы связи (представьте себе, что для вычислений отправляете очень объемную информацию - к примеру, видео высокой четкости)
Что такое граница сети?
Для устройств, подключенных к сети Интернет, границей будет точка, где это устройства непосредственно подключается к Интернету. Конечно, определение экстремально размытое; к примеру, компьютер пользователя или процессор внутри IoT камеры могут быть теми самыми точками, однако, сетевой маршрутизатор также вполне попадает под это определение. Но важно одно: граница будет гораздо ближе к устройству (с географической точки зрения), нежели к облачным серверам.
Приведем пример edge computing-а
Представим себе некое здание, в котором понаставили десятки IoT камер очень высокого разрешения. Эти камеры относительно безмозглые, т.к они просто отдают сырой видеосигнал на облако. Облако, в свою очередь, пропускает весь этот сырой видео трафик через приложение, которое умеет определять движение, чтобы хранить только максимально полезную информацию. Представьте себе требованию к Интернет-каналу в таком случае: ежесекундно передаются мегабайты информации, и к тому же получается высокая нагрузка на облачные сервера, которые занимаются вычислениями - они обязаны обрабатывать все эти огромные объемы информации.
А теперь представьте себе, что сервер, определяющий движение был помещен на границу сети (той самой, в которой находится наше воображаемое здание). Что если каждая камера будет использовать свои собственные вычислительные мощности для запуска там приложения, которое будет определять движение? Очевидно, тогда в облако будет уходить только "полезный" трафик. Кроме того, на облачные сервера ляжет только задача по хранению важной информации, что де-факто означает возможность этого облака поддерживать связь с гораздо большим количеством камер без перегрузки. Вот примерно так и выглядит пример edge computing.
Преимущества концепции edge computing
Как видно в примере выше, данный концепт позволяет минимизировать загрузку Интернет-канала и нагрузку на вычислительные мощности облака. Полоса пропускания и вычислительные мощности, к сожалению, конечны и стоят реальных денег. С каждым зданием и офисом, которые будут оборудованы "умными" камерами, принтерами, термостатами и даже тостерами, аналитики предсказывают, что к 2025 году в мире будет установлено 75 миллиардов IoT устройств. Чтобы все эти устройства корректно работали, большой процент вычислений должен быть перенесен на edge-и.
Следующее преимущество - это снижение задержки. Каждый раз, когда устройство пытается подключиться к какому-нибудь удаленному серверу, появляется задержка. Гипертрофированный пример: когда двое коллег в одном офисе чатятся в аське, они могут почувствовать сильную задержку, так как каждое сообщение "улетает" во внешний мир, подключается к некому очень удаленному серверу и также возвращается обратно в эту сеть. Если бы весь этот процесс происходил на границе сети, то эта задержка могла бы быть значительно снижена.
Также, когда пользователи используют тонны веб-приложений, которые постоянно подключаются к внешним серверам, они могут чувствовать эти самые задержки. Длительность задержек будет зависеть от того, какова их полоса пропускания и где находятся сервера, но этих задержек можно легко избежать. Правильно, если воткнуть все эти сервера на границу этой сети.
Если подытожить, то общие плюсы этого концепта таковы:
Снижение задержек
Снижение затрат путем использования более дешевых каналов связи
Снижение затрат путем уменьшения нагрузки на удаленные вычислительные ресурсы
Минусы данного подхода
На мой взгляд, есть два основных минуса: первый - это сильное увеличение сложности устройств и повышенный риск компрометации этих устройств - по сути, даже банальный термостат становится полноценным компьютером, который, как мы все знаем, может быть легко подвергнут взлому. Кроме того, из-за увеличения сложности устройств и повышения их вычислительной мощности серьезно возрастает их стоимость. Однако очевидно, что технологии шагают семимильными шагами - компьютер 30 лет назад был в тысячи раз слабее современного смартфона, а стоили они гораздо дороже.
