JSON Web Token, често наричан JWT, е отворен стандарт за сигурно прехвърляне на данни между две страни в JSON полезен товар, който може да бъде проверен и надежден чрез цифров подпис. По-просто казано, JWT е просто низ, който се изпраща в HTTP заявка от клиента към сървъра, за да потвърди автентичността на клиента.

Структура

JWT се състои от три отделни компонента, разделени с точки.

Header.Payload.Signature

Заглавка

Заглавката обикновено се състои от две части: типа на токена, който е JWT, и алгоритъма за хеширане, който се използва за създаване на компонента на подписа на JWT, като HMAC SHA256 или RSA. За напр.

{
 “alg”: “HS256”,
 “typ”: “JWT”
}

След това този JSON е Base64Url кодиран, за да формира първата част на JWT. т.е

header: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Полезен товар

Полезният товар е всички данни, които искаме да включим в JWT. Нарича се още като искове, защото когато клиент изпрати JWT в заявка, той твърди, че тази информация му принадлежи. Ако тези данни са били подправени, JWT ще бъде невалиден. Едно нещо, за което трябва да внимаваме относно полезния товар, е той да може да се чете от всеки. Така че трябва да избягваме да поставяме секретна информация тук, освен ако не е криптирана. Типичен пример за полезния товар е

{
  “user_id”: “12345”,
  “admin”: true,
  “expiry_at”: “Mon Jun 17 2019 11:12:13 GMT+0530”
}

След това този JSON също е Base64Url кодиран, за да формира втората част на JWT. т.е

payload: eyJ1c2VyX2lkIjoiMTIzNDUiLCJhZG1pbiI6InRydWUiLCJleHBpcnlfYXQiOiJNb24gSnVuIDE3IDIwMTkgMTE6MTI6MTMgR01UKzA1MzAifQ

Като цяло можем да добавим толкова полета, колкото желаем в полезния товар, но се препоръчва да го поддържаме възможно най-малък, тъй като наличието на по-голям JWT може да повлияе отрицателно на производителността и да въведе забавяне.

Подпис

Както споменах по-рано, че идеята за използване на JWT е да се провери автентичността на източника на данните, за да се направи това, алгоритъмът, посочен в заглавката, се използва за подписване на base64URL кодирана заглавка и полезен товар с помощта на таен ключ. Ние използваме HS256 алгоритъм за този пример, така че генерирането на подпис ще изглежда по следния начин.

HMACSHA256(
     base64UrlEncode(header) + "." + base64UrlEncode(payload),
     "secretKey"
)

Генерираната от него стойност ще бъде отново Base64Url кодирана, за да формира третата част на JWT. т.е.

signature: G7Wj5dGTnd5s2mbKQafSLLqV6Jqj4uMXkts3GqTViOo

Сега, ако комбинираме всички тези 3 компонента, т.е. заглавка, полезен товар и подпис имаме JWT токен, който изглежда така:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMTIzNDUiLCJhZG1pbiI6InRydWUiLCJleHBpcnlfYXQiOiJNb24gSnVuIDE3IDIwMTkgMTE6MTI6MTMgR01UKzA1MzAifQ.G7Wj5dGTnd5s2mbKQafSLLqV6Jqj4uMXkts3GqTViOo

Нека се опитаме да визуализираме как този JWT може да се използва за валидиране на автентичността на информацията, предадена в ресурсния сървър.

Тук имаме три обекта: клиент, сървър за удостоверяване и сървър за ресурси. Потребителят или клиентът ще предостави своите идентификационни данни на сървъра за удостоверяване и ако потребителят е удостоверен, той ще създаде JWT, използвайки гореспоменатата структура и ще го върне на потребителя. Сега, когато потребителят направи заявка към сървър за ресурси, използвайки този JWT токен със заглавка за оторизация, той ще генерира подписа, използвайки същия алгоритъм и ще го провери спрямо този, включен в JWT токена. Ако подписът съвпада, това означава, че данните произхождат от автентичен източник. В противен случай това би означавало, че е бил манипулиран по средата, като по този начин ни помага при идентифицирането на надушване на данни.

Едно нещо, което обаче трябва да разберем, е, че целта на JWT токените е неда скрият данните, а да потвърдят автентичността на източника на данните. Данните за полезния товар са кодирани и подписани, но не са криптирани, така че не трябва да включваме чувствителна информация в полезния товар на JWT, освен ако не са криптирани.

Това обобщава простата идея за внедряване на JWT токен в уеб приложения. Това е просто, лесно и помага за добавянето на едно допълнително ниво на доверие и сигурност в нашето приложение.