Имам нова SPA с модел за удостоверяване без състояние, използващ JWT. Често ме молят да се позова на OAuth за потоците за удостоверяване, като например да изпращам 'Bearer tokens' за всяка заявка вместо обикновена хедър токена, но мисля, че OAuth е много по-сложен от обикновеното удостоверяване, базирано на JWT. Какви са основните разлики, трябва ли да направя така, че JWT удостоверяването да се държи като OAuth?
Също така използвам JWT като моя XSRF-TOKEN, за да предотвратя XSRF, но от мен се иска да ги държа отделно? Трябва ли да ги разделям? Всяка помощ тук ще бъде оценена и може да доведе до набор от насоки за общността.
TL;DR Ако имате много прости сценарии, като например едно клиентско приложение, един API, тогава може да не се изплати преминаването към OAuth 2.0, от друга страна, при много различни клиенти (браузърни, местни мобилни, от страна на сървъра и т.н.), тогава придържането към правилата на OAuth 2.0 може да направи нещата по-управляеми, отколкото опитите за разработване на собствена система.
Както е посочено в друг отговор, JWT (Learn JSON Web Tokens) е просто формат на токен, той определя компактен и самостоятелен механизъм за предаване на данни между страните по начин, който може да бъде проверен и надежден, тъй като е цифрово подписан. Освен това правилата за кодиране на JWT също правят тези токени много лесни за използване в контекста на HTTP.
Тъй като са самостоятелни (действителният токен съдържа информация за даден субект), те също така са добър избор за прилагане на механизми за удостоверяване без състояние (известни още като Look mum, no sessions!). Когато се тръгва по този път и единственото нещо, което трябва да представи дадена страна, за да получи достъп до защитен ресурс, е самият токен, въпросният токен може да се нарече носителски токен.
На практика това, което правите, вече може да се класифицира като основано на токени на приносител. Все пак имайте предвид, че не използвате токени на приносител, както е посочено в спецификациите, свързани с OAuth 2.0 (вж. RFC 6750). Това би означавало да разчитате на HTTP заглавието Authorization
и да използвате схемата за удостоверяване Bearer
.
Що се отнася до използването на JWT за предотвратяване на CSRF, без да се знаят точните подробности, е трудно да се установи валидността на тази практика, но честно казано, тя не изглежда правилна и/или целесъобразна. Следната статия (Cookies vs Tokens: The Definitive Guide) може да бъде полезно четиво по този въпрос, особено разделът XSS and XSRF Protection.
И един последен съвет: дори ако не е необходимо да използвате изцяло OAuth 2.0, бих ви препоръчал да предавате вашия токен за достъп в хедъра Authorization
, вместо да използвате персонализирани хедъри**. Ако това наистина са токени за достъп, следвайте правилата на RFC 6750, ако ли не, винаги можете да създадете потребителска схема за удостоверяване и все пак да използвате този хедър.
Хедърите Authorization се разпознават и третират специално от HTTP прокситата и сървърите. По този начин използването на такива хедъри за изпращане на токени за достъп до ресурсни сървъри намалява вероятността от изтичане или непреднамерено съхранение на удостоверени заявки като цяло и особено на хедърите Authorization.
(източник: RFC 6819, раздел 5.4.1)
OAuth 2.0 дефинира протокол, т.е. определя как се прехвърлят токени, а JWT дефинира формат на токена.
OAuth 2.0 и "JWT удостоверяване" имат сходен външен вид, когато става въпрос за (2-рия) етап, на който клиентът представя токена на сървъра на ресурсите: токенът се предава в заглавие.
Но "JWT удостоверяване" не е стандарт и не определя как Клиентът получава токена на първо място (1-ви етап). Оттук идва и възприеманата сложност на OAuth: той също така дефинира различни начини, по които Клиентът може да получи токен за достъп от нещо, което се нарича Сървър за оторизация.
Така че истинската разлика е, че JWT е само формат на жетон, а OAuth 2.0 е протокол (който може да използва JWT като формат на жетон).
Първо, трябва да правим разлика между JWT и OAuth. По принцип JWT е формат за символи. OAuth е протокол за оторизация, който може да използва JWT като токен. OAuth използва съхранение от страна на сървъра и от страна на клиента. Ако искате да направите реално излизане от системата, трябва да използвате OAuth2. Удостоверяването с JWT токен не може да доведе до реално излизане от системата. Защото не разполагате със сървър за удостоверяване, който да следи за токени. Ако искате да предоставите API на клиенти от трети страни, трябва да използвате и OAuth2. OAuth2 е много гъвкав. Внедряването на JWT е много лесно и не отнема много време. Ако приложението ви се нуждае от подобна гъвкавост, трябва да изберете OAuth2. Но ако не се нуждаете от този сценарий на използване, внедряването на OAuth2 е загуба на време.
XSRF токенът винаги се изпраща на клиента във всяко заглавие на отговор. Няма значение дали CSRF токенът е изпратен в JWT токен или не, защото CSRF токенът е защитен със себе си. Следователно изпращането на CSRF токен в JWT е ненужно.