πŸ•Έ Π’Π΅Π±-аутСнтификация: Ρ„Π°ΠΉΠ»Ρ‹ cookies ΠΈΠ»ΠΈ Ρ‚ΠΎΠΊΠ΅Π½Ρ‹?

АутСнтификация Π½Π° основС Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ²

Π­Ρ‚ΠΎΡ‚ способ Π±Ρ‹Π» Π²Π²Π΅Π΄Π΅Π½ для устранСния основанного Π½Π° ΠΊΡƒΠΊΠ°Ρ… Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ. ΠžΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΠΈ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° – трСбуСтся ручная рСализация ΠΈ Ρ‚ΠΎΠΊΠ΅Π½Ρ‹ ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ΡΡ Π½Π° сторонС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°.

Когда Π²Ρ‹ Π²Ρ…ΠΎΠ΄ΠΈΡ‚Π΅ Π²
Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, сСрвСр провСряСт ΡƒΡ‡Π΅Ρ‚Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈ отправляСт Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ
Ρ‚ΠΎΠΊΠ΅Π½ Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€. Π‘Ρ€Π°ΡƒΠ·Π΅Ρ€ сохраняСт Ρ‚ΠΎΠΊΠ΅Π½ ΠΈ добавляСт Π΅Π³ΠΎ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ
Π±ΡƒΠ΄ΡƒΡ‰ΠΈΡ… запросов.

Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½Ρ‹Π΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ
Ρ‚ΠΎΠΊΠ΅Π½-ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° Π² Ρ€Π°Π·Ρ‹ слоТнСС описанных Π²Ρ‹ΡˆΠ΅. НапримСр, Π²
OpenID Connect примСняСтся нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ для Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… сцСнариСв использования. Π§Ρ‚ΠΎΠ±Ρ‹ Π»ΡƒΡ‡ΡˆΠ΅ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Ρ‚ΠΎΠΊΠ΅Π½Ρ‹, Ρ€Π°Π·ΠΎΠ±ΡŒΠ΅ΠΌ процСсс Π½Π° Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ части ΠΈ Π² качСствС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ JWT (JSON Web Token) – Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΡˆΠΈΡ€ΠΎΠΊΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ стандарт.

Π‘Π΅Ρ€Π²Π΅Ρ€ провСряСт ΡƒΡ‡Π΅Ρ‚Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅, Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚ΠΎΠΊΠ΅Π½, подписываСт Π΅Π³ΠΎ сСкрСтным ΠΊΠ»ΡŽΡ‡ΠΎΠΌ ΠΈ отправляСт Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€

ΠŸΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ
ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΠ΅ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, SSL) для Π·Π°Ρ‰ΠΈΡ‚Ρ‹ ΠΊΠ°Π½Π°Π»Π°.

На сторонС сСрвСра ΠΌΠΎΠΆΠ½ΠΎ
ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ NPM (Ρ‚Π°ΠΊΡƒΡŽ ΠΊΠ°ΠΊ jsonwebtoken) для
создания Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ²:

Π‘Π΅Ρ€Π²Π΅Ρ€ отправляСт Ρ„Π°ΠΉΠ» cookie Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Ρƒ, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ Π΅Π³ΠΎ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Set-Cookie

Π’ Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊ этому Π²
cookie ΠΌΠΎΠ³ΡƒΡ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒΡΡ Ρ‚Π°ΠΊΠΈΠ΅ свСдСния, ΠΊΠ°ΠΊ Π΄Π°Ρ‚Π° истСчСния срока дСйствия, Π΄ΠΎΠΌΠ΅Π½
ΠΈ возраст. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΎΡ‚Π²Π΅Ρ‚Π° с нСсколькими Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°ΠΌΠΈ cookie Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ
ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

Π‘ΠΎΡ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΠΊΠ΅Π½Π° Π² Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π° ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π² запросы с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ JavaScript

Π‘Ρ€Π°ΡƒΠ·Π΅Ρ€ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ
этот ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ Π² локальном Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅, Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ сСансов ΠΈΠ»ΠΈ Π² Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ cookies.
Π—Π°Ρ‚Π΅ΠΌ ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½ Π½Π° сторону сСрвСра
для Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ запросов.

Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΠΊΠ΅Π½Π° Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ JavaScript.

Authorization: Bearer <token>

ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ
Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ jwt.decode() ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ jsonwebtoken для дСкодирования Ρ‚ΠΎΠΊΠ΅Π½Π°.

Π‘Ρ€Π°ΡƒΠ·Π΅Ρ€ сохраняСт cookie Π² Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ ΠΈ отправляСт Π΅Π³ΠΎ с ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌΠΈ запросами

Когда сСрвСр ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ запрос с cookie, ΠΎΠ½ сравниваСт ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ сСанса Π² Ρ„Π°ΠΉΠ»Π΅ cookie с сСансом Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ… для Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.

Найти всС сохранСнныС Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅ Ρ„Π°ΠΉΠ»Ρ‹ cookie ΠΌΠΎΠΆΠ½ΠΎ Π² Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Ρ„Π°ΠΉΠ»ΠΎΠ² cookie Π² Ρ€Π°Π·Π΄Π΅Π»Π΅
прилоТСния с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ инструмСнтов Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° (devtools).

Когда ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π²Ρ‹ΠΉΠ΄Π΅Ρ‚ ΠΈΠ· систСмы, сСрвСр ΡƒΠ΄Π°Π»ΠΈΡ‚ сСанс ΠΈΠ· Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…

Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ
Π²Ρ‹ΠΉΠ΄Π΅Ρ‚ ΠΈΠ· систСмы, Ρƒ сСрвСра истСчСт срок дСйствия Ρ„Π°ΠΉΠ»Π° cookie ΠΈ сСанс Π² Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‡ΠΈΡ‰Π΅Π½. Π‘Ρ€Π°ΡƒΠ·Π΅Ρ€ Π΄Π΅Π»Π°Π΅Ρ‚ Ρ‚ΠΎ ΠΆΠ΅ самоС, удаляя Ρ„Π°ΠΉΠ» cookie ΠΈΠ· Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°.

ΠœΡ‹ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π»ΠΈΡΡŒ, ΠΊΠ°ΠΊ
Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ аутСнтификация Π½Π° основС cookie, Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ рассмотрим Ρ„ΠΈΡ‡ΠΈ, ΠΏΠ»ΡŽΡΡ‹ ΠΈ
минусы этой схСмы.

Automatic logout

НСмало вопросов Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ с automatic logout. ΠœΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ Π·Π°Π΄Π°Ρ‡Ρƒ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ ΠΏΡƒΡ‚Π΅ΠΌ манипуляции сроков дСйствия access- ΠΈ refresh-Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ². Π’ΠΎ Π΅ΡΡ‚ΡŒ послС обращСния ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΊ бэкСнду систСма Π²Ρ‹Π΄Π°Π΅Ρ‚ Π΅ΠΌΡƒ эти Ρ‚ΠΎΠΊΠ΅Π½Ρ‹ со сроком дСйствия, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½ΡƒΠΆΠ΅Π½ Ρ‡Π΅Ρ‚ΠΊΠΎ для автоматичСского Π»ΠΎΠ³Π°ΡƒΡ‚Π°. И Ρ‚ΠΎΠ³Π΄Π° Ссли Ρ‚ΠΎΠΊΠ΅Π½ просрочСн, Ρ‚ΠΎ Π»ΠΎΠ³Π°ΡƒΡ‚ состоится. НиТС Π½Π° ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° ΠΈΠΌΠ΅Π½Π½ΠΎ такая схСма:

Best practices Π² jwt

И Π² Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ ΠΏΡ€ΠΈΠ²Π΅Π΄Ρƒ best practices ΠΏΡ€ΠΈ использовании этого Π²ΠΈΠ΄Π° Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… слСдуСт ΠΏΡ€ΠΈΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒΡΡ:

Cookie-based authentication

АутСнтификация – это процСсс ΠΎΠ±ΠΌΠ΅Π½Π° ΡƒΡ‡Π΅Ρ‚Π½Ρ‹ΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ для ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. ΠŸΡ€ΠΈ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π½Π° основС cookies ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ (Ρ„Π°ΠΉΠ» cookie) создаСтся Π½Π° сторонС сСрвСра ΠΈ отправляСтся Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€.

Когда Π²Ρ‹ Π²Ρ…ΠΎΠ΄ΠΈΡ‚Π΅ Π² Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ Ρ„Π°ΠΉΠ» cookie с сСрвСра, сохраняСт Π΅Π³ΠΎ ΠΈ отправляСт с ΠΊΠ°ΠΆΠ΄Ρ‹ΠΌ
ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ запросом, Ρ‡Ρ‚ΠΎΠ±Ρ‹ сСрвСр ΠΌΠΎΠ³ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ запросы ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‚ ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈ Ρ‚ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.

Π§Ρ‚ΠΎΠ±Ρ‹ Π»ΡƒΡ‡ΡˆΠ΅ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠ°ΠΊ
Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Ρ„Π°ΠΉΠ»Ρ‹ cookie, Ρ€Π°Π·ΠΎΠ±ΡŒΠ΅ΠΌ этот процСсс Π½Π° 5 частСй.

Django rest framework

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π½ΡƒΠΆΠ½ΠΎ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Django REST Framework. Django REST Framework большой ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ, для Ρ‚Π΅Ρ…, ΠΊΡ‚ΠΎ Ρ…ΠΎΡ‡Π΅Ρ‚ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ одностраничныС прилоТСния ΠΈ API для Π½ΠΈΡ….

ΠœΡ‹ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Django REST Framework, поэтому Ссли Π²Ρ‹ Π½Π΅ Π·Π½Π°ΠΊΠΎΠΌΡ‹ с Π½ΠΈΠΌ, посмотритС Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ.

Для установки Django REST Framework, Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ:

$ pip install djangorestframework


Django REST Framework Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ ΠΊ вашим установлСнным прилоТСниям (INSTALLED_APPS Π² django_angular_token_auth/settings.py:)

INSTALLED_APPS = (
    ...,
    'rest_framework',
)

Π’Π°ΠΊ ΠΆΠ΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π² django_angular_token_auth/settings.py:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ), 
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
}

ΠœΡ‹ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ SessionAuthentication ΠΈΠ»ΠΈ BasicAuthentication, Π½ΠΎ ΠΎΠ½ΠΈ ΠΈΠΌΠ΅ΡŽΡ‚ΡΡ Π² Django REST Framework ΠΈ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°ΡŽΡ‚ работоспособный API ΠΈΠ· ΠΊΠΎΡ€ΠΎΠ±ΠΊΠΈ.

Django-rest-framework-jwt

ПослСднСС, Ρ‡Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ, это ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ django-rest-framework-jwt. Π­Ρ‚ΠΎΡ‚ ΠΏΠ°ΠΊΠ΅Ρ‚ обСспСчиваСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ JWT для Django REST Framework ΠΈ Π² качСствС JSON Web Token ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ PyJWT. Π§Ρ‚ΠΎ Π±Ρ‹ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ django-rest-framework-jwt Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ:

$ pip install djangorestframework-jwt

НуТно Π±ΡƒΠ΄Π΅Ρ‚ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π² django_angular_token_auth/settings.py:

import datetime
JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=14)
}

Π­Ρ‚ΠΎΡ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ срок ΠΆΠΈΠ·Π½ΠΈ для Π½Π°ΡˆΠΈΡ… ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ΠΎΠ² ΠΈ Π² нашСм случаС это Π±ΡƒΠ΄Π΅Ρ‚ 14 Π΄Π½Π΅ΠΉ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΅Π³ΠΎ, исходя ΠΈΠ· собствСнных ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚Π΅Π½ΠΈΠΉ.

Π’Ρ‹ Ρ‚Π°ΠΊ ΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½Π½Ρ‹Π΅ настройки REST_FRAMEWORK:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
   )
}

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ:’rest_framework_jwt.authentication.JSONWebTokenAuthentication’, Π² ‘DEFAULT_AUTHENTICATION_CLASSES’.

Header

The header typically consists of two parts: the type of the token, which is JWT, and the signing algorithm being used, such as HMAC SHA256 or RSA.

For example:

{
  "alg": "HS256",
  "typ": "JWT"
}

Then, this JSON is Base64Url encoded to form the first part of the JWT.

Json web tokens

Учитывая ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, Π² сообщСствС Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² ΠΌΠ½ΠΎΠ³ΠΎ Π»Π΅Ρ‚ Π½Π°Π·Π°Π΄ появилась идСя ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ΠΊΡƒΡŽ строку, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ с ΠΎΠ΄Π½ΠΎΠΉ стороны Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ΄Π΄Π΅Π»Π°Ρ‚ΡŒ, с Π΄Ρ€ΡƒΠ³ΠΎΠΉ β€” ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ рСсурсный сСрвСр ΠΌΠΎΠ³ Π±Ρ‹ сам ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Π½Π° Π²Π°Π»ΠΈΠ΄Π½ΠΎΡΡ‚ΡŒ. Π’ качСствС Ρ‚Π°ΠΊΠΎΠΉ строки оказалось ΡƒΠ΄ΠΎΠ±Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ JWT β€” JSON Web Token.

JWT прСдставляСт собой строку ΠΈΠ· Ρ‚Ρ€Π΅Ρ… частСй, Ρ€Π°Π·Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… Ρ‚ΠΎΡ‡ΠΊΠ°ΠΌΠΈ. На ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ Π½ΠΈΠΆΠ΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Ρ‹ значСния ΠΊΠ°ΠΆΠ΄ΠΎΠΉ части:

ΠŸΡ€ΠΈ этом ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΈ Π²Ρ‚ΠΎΡ€ΡƒΡŽ части Π½Π΅ составит Ρ‚Ρ€ΡƒΠ΄Π° для любого ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, ΠΈΠΌΠ΅ΡŽΡ‰Π΅Π³ΠΎ Ρ‚ΠΎΡ‚ самый двусторонний Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ.

Но Π½ΠΈΠΊΡ‚ΠΎ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ записанноС Π² Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ΠΉ части β€” ΠΈ соотвСтствСнно Π½ΠΈΠΊΡ‚ΠΎ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ΄Π΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚ΠΎΠΊΠ΅Π½.

Если Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΡƒΠΊΠ°ΠΆΠ΅Ρ‚ Π²ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΉ части Π΄Ρ€ΡƒΠ³ΠΎΠ΅ имя ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, Ρ‚ΠΎ измСнится ΠΈ подпись Π² Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ΠΉ части. Но ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρƒ Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊΠ° Π½Π΅Ρ‚ сСкрСтного ΠΊΠ»ΡŽΡ‡Π°, Ρ‚ΠΎ ΠΎΠ½ Π½Π΅ смоТСт ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΏΠΎΠ΄ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ‚ΠΎΠΊΠ΅Π½. JWT попросту Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Π°Π»ΠΈΠ΄Π½Ρ‹ΠΌ.

ΠŸΠ΅Ρ€Π΅ΠΉΠ΄Π΅ΠΌ ΠΊ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ схСмС Π½Π° ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ Π½ΠΈΠΆΠ΅. Π‘Ρ…Π΅ΠΌΠ° ΠΏΠΎΡ…ΠΎΠΆΠ° Π½Π° Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ сСссий, Π½ΠΎ Π΅ΡΡ‚ΡŒ ΠΎΠ΄Π½ΠΎ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅. ПослС ввСдСния ΠΊΡ€Π΅Π΄ΠΎΠ² сСрвСр Π΄Π°Π΅Ρ‚ ΡŽΠ·Π΅Ρ€Ρƒ Π½Π΅ cookies с Session ID, Π° Ρ‚ΠΎΠΊΠ΅Π½. Π—Π°Ρ‚Π΅ΠΌ клиСнтскоС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ добавляСт Ρ‚ΠΎΠΊΠ΅Π½ ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ запросу Π² Π²ΠΈΠ΄Π΅ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Authorization.

ΠŸΡ€ΠΈ этом ΠΎΠ½ΠΎ вписываСт Π² Π½Π΅Π³ΠΎ слово Β«BearerΒ» (ΠΏΡ€Π΅Π΄ΡŠΡΠ²ΠΈΡ‚Π΅Π»ΡŒ), Π° послС ΠΏΡ€ΠΎΠ±Π΅Π»Π° β€” сам Ρ‚ΠΎΠΊΠ΅Π½. Π’Π°ΠΊΠΆΠ΅ Π½Π° схСмС прСдставлСн Auth middleware. Π­Ρ‚ΠΎ достаточно стандартная Ρ‡Π°ΡΡ‚ΡŒ любого Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°, которая ΡƒΠΌΠ΅Π΅Ρ‚ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ, Π² частности, Π²Π°Π»ΠΈΠ΄Π½ΠΎΡΡ‚ΡŒ Ρ‚ΠΎΠΊΠ΅Π½Π°. Π’ΠΎ Π΅ΡΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° сСрвСрС ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ этап ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ.

Если Ρ‚ΠΎΠΊΠ΅Π½ Π½Π΅ заэкспайрился ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ подписан с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ сСкрСтной строки, Ρ‚ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΏΡ€ΠΈ использовании Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹ микросСрвисов Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ запрос ΠΊ рСсурсным сСрвСрам ΠΏΡ€ΠΎΠ³ΠΎΠ½ΡΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· сСрвСр Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ.

Logout ΠΈ only one active device

Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ рассмотрим Π·Π°Π΄Π°Ρ‡ΠΈ Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ Logout ΠΈ Only one active device. Π‘Π°ΠΌΠΈ ΠΏΠΎ сСбС Ρ‚ΠΎΠΊΠ΅Π½Ρ‹ Π·Π°Π΄ΡƒΠΌΠ°Π½Ρ‹ ΠΊΠ°ΠΊ stateless, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ ΠΎΠ½ΠΈ Π½Π΅ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Ρ‹ для размСщСния Π½Π° сСрвСрС. А идСя Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅Π΄ΡƒΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ хранСния ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ Π½ΠΈΡ… Π½Π° сСрвСрС.

Π’Π°ΠΊΠΈΠ΅ Ρ‚ΠΎΠΊΠ΅Π½Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒΡΡ Π² Β«Ρ‡Π΅Ρ€Π½ΠΎΠΌ спискС», ΠΏΠΎΠΊΠ° Π½Π΅ истСчСт срок ΠΈΡ… использования. Π‘ Π΄Ρ€ΡƒΠ³ΠΎΠΉ стороны, ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½Π° сСрвСрС whitelist, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ Π΄Π°ΠΆΠ΅ нСсколько ΠΏΡ€ΠΎΡ‰Π΅. Π­Ρ‚ΠΎΡ‚ список станСт рССстром Π²Ρ‹Π΄Π°Π½Π½Ρ‹Ρ… Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ², с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ²Π΅Ρ€ΡΡ‚ΡŒΡΡ систСма. Если ΠΏΡ€Π΅Π΄ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹ΠΉ ΡŽΠ·Π΅Ρ€ΠΎΠΌ Ρ‚ΠΎΠΊΠ΅Π½ Π½Π΅ просрочСн ΠΈ ΡƒΠΊΠ°Π·Π°Π½ Π² Β«Π±Π΅Π»ΠΎΠΌ спискС», Ρ‚ΠΎ ΠΎΠ½ Π²Π°Π»ΠΈΠ΄Π΅Π½.

Π₯Ρ€Π°Π½Π΅Π½ΠΈΠ΅ самих Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ² Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ… слоТно Π½Π°Π·Π²Π°Ρ‚ΡŒ бСзопасным. МоТно Π»ΠΈ ΠΊΠ°ΠΊ-Ρ‚ΠΎ Π²Ρ‹ΠΉΡ‚ΠΈ ΠΈΠ· этой  ситуации? Π”Π°. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΡŽ Π½ΠΈΠΆΠ΅: Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ payload добавился ΠΏΡƒΠ½ΠΊΡ‚ hash. Π­Ρ‚ΠΎ нСкая Ρ€Π°Π½Π΄ΠΎΠΌΠ½ΠΎ сформированная строка. Она записываСтся Π² payload Ρ‚ΠΎΠΊΠ΅Π½Π° ΠΈ Π² Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Π½Π° сСрвСрС с привязкой ΠΊ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.

Когда ΡŽΠ·Π΅Ρ€ ΠΏΡ€Π΅Π΄ΡŠΡΠ²Π»ΡΠ΅Ρ‚ Ρ‚ΠΎΠΊΠ΅Π½, систСма парсит Π΅Π³ΠΎ, провСряСт срок дСйствия Ρ‚ΠΎΠΊΠ΅Π½Π° ΠΈ Π΅Π³ΠΎ подпись сСкрСтной строкой. Π—Π°Ρ‚Π΅ΠΌ вытаскиваСт hash ΠΈ свСряСт Π΅Π³ΠΎ с ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΌ ID Π² Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ key-value Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅, основная Π±Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠ΅ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ прСдоставит соврСмСнный Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ.

Payload ΠΈΠ»ΠΈ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅

Π’Ρ‚ΠΎΡ€Ρ‹ΠΌ Π±Π»ΠΎΠΊΠΎΠΌ ΠΈΠ΄Π΅Ρ‚ eyJ1c2VyX2lkIjoxLCJleHAiOjE1ODEzNTcwMzl9

Π­Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅, Ρ‚Π°ΠΊ ΠΆΠ΅ Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π² Base64. ПослС раскодирования ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ:

Signature

To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.

For example if you want to use the HMAC SHA256 algorithm, the signature will be created in the following way:

HMACSHA256(
  base64UrlEncode(header)   "."  
  base64UrlEncode(payload),
  secret)

The signature is used to verify the message wasn’t changed along the way, and, in the case of tokens signed with a private key, it can also verify that the sender of the JWT is who it says it is.

Url-адрСса

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π½ΡƒΠΆΠ½ΠΎ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ URL-адрСса для нашСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°.

ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ django_angular_token_auth/urls.py ΠΈ ΠΏΡ€ΠΈΠ²Π΅Π΄ΠΈΡ‚Π΅ Π΅Π³ΠΎ ΠΊ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌΡƒ Π²ΠΈΠ΄Ρƒ:

What is json web token?

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed.

Although JWTs can be encrypted to also provide secrecy between parties, we will focus on signed tokens. Signed tokens can verify the integrity of the claims contained within it, while encrypted tokens hide those claims from other parties.

What is the json web token structure?

In its compact form, JSON Web Tokens consist of three parts separated by dots (.), which are:

Therefore, a JWT typically looks like the following.

xxxxx.yyyyy.zzzzz

Let’s break down the different parts.

When should you use json web tokens?

Here are some scenarios where JSON Web Tokens are useful:

Why should we use json web tokens?

Let’s talk about the benefits of JSON Web Tokens (JWT) when compared to Simple Web Tokens (SWT) and Security Assertion Markup Language Tokens (SAML).

Π‘Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ

Cookie Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ Π½Π°Π΄Π΅ΠΆΠ½ΠΎΠΉ Π·Π°Ρ‰ΠΈΡ‚Ρ‹ ΠΎΡ‚ Π°Ρ‚Π°ΠΊ, ΠΈ ΠΎΠ½ΠΈ Π² основном уязвимы для Π°Ρ‚Π°ΠΊ с использованиСм мСТсайтового скриптинга (XSS) ΠΈ ΠΏΠΎΠ΄Π΄Π΅Π»ΠΊΠΈ мСТсайтовых запросов (CSRF).

ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ явно ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ² cookie, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°Ρ‰ΠΈΡ‚ΠΈΡ‚ΡŒ ΠΈΡ… ΠΎΡ‚ Ρ‚Π°ΠΊΠΈΡ… Π°Ρ‚Π°ΠΊ.

Π’ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΉ части

На этом ΠΌΡ‹ остановимся. Π’ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΉ части, построим клиСнтскоС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ Π² основном сосрСдоточимся Π½Π° рСгистрации ΠΈ сСансС Π²Ρ…ΠΎΠ΄Π° Π² систСму. НапишСм сСрвис, для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎ Π±Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ Π·Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΈΠ· систСмы.

Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ

По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ содСрТит Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΈΠΏ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π° ΠΈ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ для ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΡ.

Π’ΠΈΠΏ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π° хранится Π² ΠΊΠ»ΡŽΡ‡Π΅ Β«typΒ». ΠšΠ»ΡŽΡ‡ Β«typΒ» игнорируСтся Π² JWT (для этой ΡΡ‚Π°Ρ‚ΡŒΠΈ это Π½Π΅ Π²Π°ΠΆΠ½ΠΎ, Π½ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅

, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ·Π½Π°Ρ‚ΡŒ ΠΏΠΎΡ‡Π΅ΠΌΡƒ). Если ΠΊΠ»ΡŽΡ‡ Β«typΒ» присутствуСт, Π΅Π³ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ JWT, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ этот ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ являСтся JSON Web Token.

Π’Ρ‚ΠΎΡ€ΠΎΠΉ ΠΊΠ»ΡŽΡ‡ Β«algΒ» опрСдСляСт Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ для ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΡ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π°. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ установлСн Π² HS256. Π•ΡΡ‚ΡŒ Ρ†Π΅Π»Ρ‹ΠΉ ряд Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹Ρ… Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… рСализациях. ΠŸΠΎΠ»Π½Ρ‹ΠΉ список с Ρ€Π°Π·Π±ΠΈΠ²ΠΊΠΎΠΉ ΠΏΠΎ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°ΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° vhod-v-lichnyj-kabinet.ru.

Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ кодируСтся Π² base64.

Π—Π°Ρ‡Π΅ΠΌ 2 Ρ‚ΠΎΠΊΠ΅Π½Π°?

ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΠΌ ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡŽ, ΠΊΠΎΠ³Π΄Π° Ρƒ нас ΠΊΠ°ΠΊΠΈΠΌ-Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΡƒΠΊΡ€Π°Π»ΠΈ Access Ρ‚ΠΎΠΊΠ΅Π½. Π”Π°, это ΡƒΠΆΠ΅ ΠΏΠ»ΠΎΡ…ΠΎ ΠΈ Π³Π΄Π΅-Ρ‚ΠΎ Ρƒ нас Π±Ρ€Π΅ΡˆΡŒ Π² бСзопасности. Π—Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊ Π² этом случаС смоТСт ΠΈΠΌ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ Ρ‡Π΅ΠΌ Π½Π° 15-30 ΠΌΠΈΠ½ΡƒΡ‚. ПослС Ρ‡Π΅Π³ΠΎ Ρ‚ΠΎΠΊΠ΅Π½ “ΠΏΡ€ΠΎΡ‚ΡƒΡ…Π½Π΅Ρ‚” ΠΈ пСрСстанСт Π±Ρ‹Ρ‚ΡŒ Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΌ. Π’Π΅Π΄ΡŒ Π½ΡƒΠΆΠ΅Π½ Π²Ρ‚ΠΎΡ€ΠΎΠΉ Ρ‚ΠΎΠΊΠ΅Π½ для продлСния.

Если ΡƒΠΊΡ€Π°Π»ΠΈ Refresh Ρ‚ΠΎΠΊΠ΅Π½, Ρ‚ΠΎ Π±Π΅Π· Access Ρ‚ΠΎΠΊΠ΅Π½Π° (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ нСдоступСн Π² JS) ΠΏΡ€ΠΎΠ΄Π»ΠΈΡ‚ΡŒ Π½ΠΈΡ‡Π΅Π³ΠΎ нСльзя ΠΈ ΠΎΠ½ оказываСтся просто бСсполСзным.

ИспользованиС Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° Ρ…Π΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ none

Подобная Π°Ρ‚Π°ΠΊΠ° происходит, ΠΊΠΎΠ³Π΄Π° Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊ измСняСт Ρ‚ΠΎΠΊΠ΅Π½, Π° Ρ‚Π°ΠΊΠΆΠ΅ мСняСт Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ Ρ…Π΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ (ΠΏΠΎΠ»Π΅ β€œalg”), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово none, Ρ‡Ρ‚ΠΎ Ρ†Π΅Π»ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ Ρ‚ΠΎΠΊΠ΅Π½Π° ΡƒΠΆΠ΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€Π΅Π½Π°. НСкоторыС Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ рассматривали Ρ‚ΠΎΠΊΠ΅Π½Ρ‹, подписанныС с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° none, ΠΊΠ°ΠΊ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΎΠΊΠ΅Π½ с ΠΏΡ€ΠΎΠ²Π΅Ρ€Π΅Π½Π½ΠΎΠΉ подписью, поэтому Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊ ΠΌΠΎΠ³ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΏΠΎΠ»Π΅Π·Π½ΡƒΡŽ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ (payload) Ρ‚ΠΎΠΊΠ΅Π½Π°, ΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ довСряло Π±Ρ‹ Ρ‚ΠΎΠΊΠ΅Π½Ρƒ.

Для прСдотвращСния Π°Ρ‚Π°ΠΊΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ JWT, которая Π½Π΅ ΠΏΠΎΠ΄Π²Π΅Ρ€ΠΆΠ΅Π½Π° Π΄Π°Π½Π½ΠΎΠΉ уязвимости. Π’Π°ΠΊΠΆΠ΅ Π²ΠΎ врСмя ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ валидности Ρ‚ΠΎΠΊΠ΅Π½Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ явно Π·Π°ΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ использованиС ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΠΎΠ³ΠΎ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ°.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ:

// ΠšΠ»ΡŽΡ‡ HMAC хранится ΠΊΠ°ΠΊ String Π² памяти JVM
private transient byte[] keyHMAC = ...;

...

// Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ контСкста Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ для запроса ΠΊ Ρ‚ΠΎΠΊΠ΅Π½Ρƒ
// Π―Π²Π½ΠΎ указываСтся использованиС HMAC-256 Ρ…Π΅Ρˆ-Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ°
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(keyHMAC)).build();

// ВСрификация Ρ‚ΠΎΠΊΠ΅Π½Π°
DecodedJWT decodedToken = verifier.verify(token);

ИспользованиС слабого ΠΊΠ»ΡŽΡ‡Π° ΠΏΡ€ΠΈ создании Ρ‚ΠΎΠΊΠ΅Π½Π°

Если сСкрСт, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ Π² случаС Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° HMAC-SHA256, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ΠΉ для подписи Ρ‚ΠΎΠΊΠ΅Π½Π°, являСтся слабым, Ρ‚ΠΎ ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π²Π·Π»ΠΎΠΌΠ°Π½ (ΠΏΠΎΠ΄ΠΎΠ±Ρ€Π°Π½ c ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π°Ρ‚Π°ΠΊΠΈ Π³Ρ€ΡƒΠ±ΠΎΠΉ силы). Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ΄Π΄Π΅Π»Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΎΠΊΠ΅Π½ с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния подписи.

Для прСдотвращСния этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π½Π°Π΄ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ слоТный сСкрСтный ΠΊΠ»ΡŽΡ‡: Π±ΡƒΠΊΠ²Π΅Π½Π½ΠΎ-Ρ†ΠΈΡ„Ρ€ΠΎΠ²ΠΎΠΉ (ΡΠΌΠ΅ΡˆΠ°Π½Π½Ρ‹ΠΉ рСгистр) ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ символы.

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΊΠ»ΡŽΡ‡ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π½Ρ‹Ρ… вычислСний, Ρ€Π°Π·ΠΌΠ΅Ρ€ сСкрСтного ΠΊΠ»ΡŽΡ‡Π° ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°Ρ‚ΡŒ 50 ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΉ.

НапримСр:

A&'/}Z57M(2hNg=;LE?~]YtRMS5(yZ<vcZTA3N-($>2j:ZeX-BGftaVk`)jKP~q?,jk)EMbgt*kW'

Для ΠΎΡ†Π΅Π½ΠΊΠΈ слоТности сСкрСтного ΠΊΠ»ΡŽΡ‡Π°, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ для вашСй подписи Ρ‚ΠΎΠΊΠ΅Π½Π°, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π°Ρ‚Π°ΠΊΡƒ ΠΏΠΎ ΡΠ»ΠΎΠ²Π°Ρ€ΡŽ ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ ΠΊ Ρ‚ΠΎΠΊΠ΅Π½Ρƒ Π² сочСтании с JWT API.

ΠœΠΎΠ³ΡƒΡ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ с ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΡƒΠ΅ΠΌΠΎΡΡ‚ΡŒΡŽ

Как ΡƒΠΆΠ΅ объяснялось, сСрвСр ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ Ρ„Π°ΠΉΠ»ΠΎΠ² cookie, ΠΈ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ сСансы Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ… для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.

Π₯отя ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Ρ…ΠΎΡ€ΠΎΡˆΠΎ
Π·Π°Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°Π²ΡˆΠΈΠ΅ сСбя способы управлСния ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΡƒΠ΅ΠΌΠΎΡΡ‚ΡŒΡŽ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€,
использованиС для хранСния сСансов Π‘Π£Π‘Π” Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ Redis), это всС Ρ€Π°Π²Π½ΠΎ
добавляСт слоТности. По ΠΌΠ΅Ρ€Π΅ роста количСства ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ, ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ
ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ с ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ сСансами.

НС ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для api

Если Π²Ρ‹ создаСтС API для прСдоставлСния услуг ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ, cookie – это Π½Π΅ Π»ΡƒΡ‡ΡˆΠΈΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚. Если ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π½Π΅ являСтся Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠΌ, это услоТнит Ρ€Π°Π±ΠΎΡ‚Ρƒ.

НапримСр, Ссли Π²Ρ‹
Ρ€Π°Π·Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚Π΅ мобильноС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠ² cookie услоТнит ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅
Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠΌ.

ΠžΠ±Ρ‹Ρ‡Π½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Π² ΠΎΠ΄Π½ΠΎΠΌ Π΄ΠΎΠΌΠ΅Π½Π΅

Π€Π°ΠΉΠ»Ρ‹ cookie Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΎΠ΄Π½ΠΎΠΌ Π΄ΠΎΠΌΠ΅Π½Π΅, Ссли Π²Ρ‹ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ ΠΈΡ… Π½Π΅ настроили.

Π₯отя со стороны это
выглядит ΠΊΠ°ΠΊ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅, Π½ΠΎ это ΠΎΠ΄Π½Π° ΠΈΠ· самых ΡΠΈΠ»ΡŒΠ½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ для обСспСчСния
Π΅Π΄ΠΈΠ½ΠΎΠ³ΠΎ источника.

Если ваш Ρ„Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄
ΠΈ бэкСнд Π»Π΅ΠΆΠ°Ρ‚ Π² Ρ€Π°Π·Π½Ρ‹Ρ… Π΄ΠΎΠΌΠ΅Π½Π°Ρ… ΠΈΠ»ΠΈ ΠΏΠΎΠ΄Π΄ΠΎΠΌΠ΅Π½Π°Ρ…, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ явно ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ это
Π² Ρ„Π°ΠΉΠ»Π΅ cookie Π² Π±Π΅Π»ΠΎΠΌ спискС. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ Π½Π΅ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ ΠΊΡƒΠΊΠΈ вмСстС
с запросом.

ΠŸΠ°Ρ€Π° слов ΠΎ бСзопасности Π΄Π°Π½Π½Ρ‹Ρ…

Π’Π΅ΠΏΠ΅Ρ€ΡŒ, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π»ΠΈΡΡŒ Π² устройствС ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ JSON Π²Π΅Π±-Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ², Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ СстСствСнный вопрос – Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Ρ‹ Π»ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅?

ΠœΡ‹ Π²ΠΈΠ΄Π΅Π»ΠΈ, Ρ‡Ρ‚ΠΎ Ρ‚ΠΎΠΊΠ΅Π½ кодируСтся ΠΈ подписываСтся, Π½ΠΎ – Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅! – Π½Π΅ ΡˆΠΈΡ„Ρ€ΡƒΠ΅Ρ‚ΡΡ! (Π² Ρ‡Π΅ΠΌ Ρ€Π°Π·Π½ΠΈΡ†Π° ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΈ ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ?) Π’ΠΎ Π΅ΡΡ‚ΡŒ эта ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π΅ обСспСчиваСт Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Ρ…. НСт Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΠΈ сохранности, поэтому Π½Π΅ слСдуСт ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π² Ρ‚ΠΎΠΊΠ΅Π½Π°Ρ… Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΠΊΠΎΠ½Ρ„ΠΈΠ΄Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅.

ΠŸΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ²

Атака происходит, ΠΊΠΎΠ³Π΄Π° Ρ‚ΠΎΠΊΠ΅Π½ Π±Ρ‹Π» ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‡Π΅Π½ ΠΈΠ»ΠΈ ΡƒΠΊΡ€Π°Π΄Π΅Π½ Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊΠΎΠΌ ΠΈ ΠΎΠ½ примСняСт Π΅Π³ΠΎ для получСния доступа ΠΊ систСмС, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.

Π—Π°Ρ‰ΠΈΡ‚Π° Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ Β«ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ контСкста» Π² Ρ‚ΠΎΠΊΠ΅Π½. ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ контСкст Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΡΡ‚ΠΎΡΡ‚ΡŒ ΠΈΠ· ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ:

ΠŸΠΎΠ΄ΠΏΠΈΡΡ‹Π²Π°Π΅ΠΌΡΡ ΠΏΠΎΠ΄ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ

И людям, ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°ΠΌ Π½ΡƒΠΆΠ½ΠΎ Π·Π½Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π΄Π°Π½Π½Ρ‹Π΅ Π±Ρ‹Π»ΠΈ созданы Π΄ΠΎΠ²Π΅Ρ€Π΅Π½Π½Ρ‹ΠΌ источником ΠΈ ΠΎΡΡ‚Π°Π»ΠΈΡΡŒ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ. Для этого Π±Ρ‹Π»Π° ΠΏΡ€ΠΈΠ΄ΡƒΠΌΠ°Π½Π° тСхнология Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ Ρ…Π΅ΡˆΠ° (подписи), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚ Ρ†Π΅Π»ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΈ Π΄ΠΎΡΡ‚ΠΎΠ²Π΅Ρ€Π½ΠΎΡΡ‚ΡŒ Π΅Π΅ отправитСля/создатСля. Для создания этой самой подписи ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ схСма ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… шагов, Ρ†Π΅Π»ΡŒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… β€” Π·Π°Ρ‰ΠΈΡ‚ΠΈΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΎΡ‚ ΠΏΠΎΠ΄Π΄Π΅Π»ΠΊΠΈ.

Π‘Ρ…Π΅ΠΌΠ° Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ HMAC (hash-based message authentication code), ΠΊΠΎΠ΄Π° Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ сообщСний с использованиСм Ρ…Π΅Ρˆ-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ
Π‘Ρ…Π΅ΠΌΠ° Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ HMAC (hash-based message authentication code), ΠΊΠΎΠ΄Π° Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ сообщСний с использованиСм Ρ…Π΅Ρˆ-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

Алгоритм Ρ…Π΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ, Π½ΠΎ ΡΡƒΡ‚ΡŒ этого ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° проста ΠΈ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½Π°: для подтвСрТдСния цСлостности сообщСния Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ снова Π½Π°ΠΉΡ‚ΠΈ подпись Π·Π°Ρ‰ΠΈΡ‰Π°Π΅ΠΌΡ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ ΡΡ€Π°Π²Π½ΠΈΡ‚ΡŒ Π΅Π΅ с ΠΈΠΌΠ΅ΡŽΡ‰Π΅ΠΉΡΡ подписью.

Подпись

Когда Ρƒ нас Π΅ΡΡ‚ΡŒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈ полСзная Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ°, ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚ΡŒ подпись.

БСрутся Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π² base64: Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈ полСзная Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ°, ΠΎΠ½ΠΈ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ Π² строку Ρ‡Π΅Ρ€Π΅Π· Ρ‚ΠΎΡ‡ΠΊΡƒ. Π—Π°Ρ‚Π΅ΠΌ эта строка ΠΈ сСкрСтный ΠΊΠ»ΡŽΡ‡ поступаСт Π½Π° Π²Ρ…ΠΎΠ΄ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΡ, ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅ (ΠΊΠ»ΡŽΡ‡ Β«algΒ»). ΠšΠ»ΡŽΡ‡ΠΎΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ любая строка. Π‘ΠΎΠ»Π΅Π΅ Π΄Π»ΠΈΠ½Π½Ρ‹Π΅ строки Π±ΡƒΠ΄ΡƒΡ‚ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½Π΅Π΅, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ потрСбуСтся большС Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π½Π° ΠΏΠΎΠ΄Π±ΠΎΡ€.

ΠŸΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для хранСния Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ этот ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ сСссии для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠΊΡ€Π΅ΠΏΠ»Π΅Π½Π½Ρ‹Π΅ ΠΊ Π½ΠΈΠΌ Π΄Π°Π½Π½Ρ‹Π΅.

Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„Π°ΠΉΠ»ΠΎΠ² cookie ΠΈ
сСссий ΠΌΠΎΠΆΠ½ΠΎ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ пСрсонализации, контроля доступа ΠΈ сами сСссии – это позволяСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ…
для ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… запросов.

ВсС эти манипуляции ΠΌΠΎΠΆΠ½ΠΎ провСсти ΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ². НапримСр, Ρ‚ΠΎΠΊΠ΅Π½Ρ‹ JWT ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Claim-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ это ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ‚ΠΎΠΊΠ΅Π½Π°, сохранСниС большСго ΠΈΡ… количСства повлияСт Π½Π° Π½Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ сСти.

Π­Ρ‚ΠΎ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ смысла, Ссли
Ρ€Π΅Ρ‡ΡŒ ΠΈΠ΄Π΅Ρ‚ ΠΎΠ± ΠΎΠ΄Π½ΠΎΠΌ запросС, Π½ΠΎ прСимущСства становятся Π·Π°ΠΌΠ΅Ρ‚Π½Ρ‹, ΠΊΠΎΠ³Π΄Π° всС
агрСгируСтся ΠΈ ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ.

ПолСзная Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ°

Π’ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ хранится любая информация, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π½ΡƒΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ Π² ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ извСстСн ΠΊΠ°ΠΊ «заявлСниС». К ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, рассмотрим ΡΠΎΡ†ΠΈΠ°Π»ΡŒΠ½ΡƒΡŽ ΡΠ΅Ρ‚ΡŒ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒΡΡ ΠΊ сообщСству ΠΌΠΎΠΆΠ½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎ ΠΏΡ€ΠΈΠ³Π»Π°ΡˆΠ΅Π½ΠΈΡŽ. Когда ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΡ€ΠΈΠ³Π»Π°ΡΠΈΡ‚ΡŒ ΠΊΠΎΠ³ΠΎ-Ρ‚ΠΎ Π² сообщСство, ΠΌΡ‹ отправляСм Π΅ΠΌΡƒ письмо с ΠΏΡ€ΠΈΠ³Π»Π°ΡˆΠ΅Π½ΠΈΠ΅ΠΌ.

{
    "email": "[email protected]"
}
 

ΠšΠ»ΡŽΡ‡ΠΈ Π² ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΌΠΈ. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π΅ΡΡ‚ΡŒ нСсколько Π·Π°Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½ΡƒΠΆΠ½ΠΎ Π·Π½Π°Ρ‚ΡŒ:

JWT Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²ΠΎ всСх Π΅Π³ΠΎ рСализациях ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Ρ‹ с ΠΈΡΡ‚Π΅ΠΊΡˆΠΈΠΌ сроком дСйствия ΠΎΡ‚ΠΊΠ»ΠΎΠ½ΡΠ»ΠΈΡΡŒ. Π’

ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΊΠ»ΡŽΡ‡ΠΈ, для ΡƒΡ‡Π΅Ρ‚Π° рассинхронизации Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. exp ΠΊΠ»ΡŽΡ‡ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΊΠΎΠΉ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π² unix Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅.

Π’Π°ΠΆΠ½ΠΎ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ полСзная Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Π½Π΅ пСрСдаСтся Π² Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ Π²ΠΈΠ΄Π΅ (хотя, ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌΠΈ ΠΈ Ρ‚ΠΎΠ³Π΄Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅). ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Π² Π½Π΅ΠΉ нСльзя Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π»ΡŽΠ±ΡƒΡŽ ΡΠ΅ΠΊΡ€Π΅Ρ‚Π½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ. НапримСр, ΠΏΠ°Ρ€ΠΎΠ»ΠΈ, Π½ΠΎΠΌΠ΅Ρ€Π° ΡΠΎΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ страхования ΠΈ Ρ‚.Π΄.


Как ΠΈ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ, полСзная Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ° кодируСтся Π² base64.

ΠŸΠΎΡΡ‚ΡΠΊΡ€ΠΈΠΏΡ‚ΡƒΠΌ

Π’ своСй Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Refresh Ρ‚ΠΎΠΊΠ΅Π½Π° использовал ΠΎΠ±Ρ‰ΡƒΡŽ Π΄Π»ΠΈΠ½Ρƒ 24 Π·Π½Π°ΠΊΠ°. ΠŸΠ΅Ρ€Π²Ρ‹Π΅ 6 Π·Π½Π°ΠΊΠΎΠ² – это Π΄Π°Ρ‚Π° Π΅Π³ΠΎ “протухания”, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ 12 Π·Π½Π°ΠΊΠΎΠ² – случайно сгСнСрированныС Π΄Π°Π½Π½Ρ‹Π΅. И Π² ΠΊΠΎΠ½Ρ†Π΅ 6 Π·Π½Π°ΠΊΠΎΠ² – это Ρ‡Π°ΡΡ‚ΡŒ Access Ρ‚ΠΎΠΊΠ΅Π½Π° послСднСй части сигнатуры.

Π”Π°Ρ‚Ρƒ протухания Π²Π½Π΅Π΄Ρ€ΠΈΠ» прям Π² Ρ‚ΠΎΠΊΠ΅Π½ с Ρ‚ΠΎΠΉ Ρ†Π΅Π»ΡŒΡŽ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ эту ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ Π³Π΄Π΅-Ρ‚ΠΎ Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ мСстС, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ….

Π”Π°Ρ‚Π° содСрТит Π³ΠΎΠ΄, мСсяц, дСнь, час ΠΈ ΠΌΠΈΠ½ΡƒΡ‚Ρ‹. Π₯ранится Π² ASCII

ΠšΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π΄Π°Ρ‚Ρ‹ Π½Π° Golang:

// ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΠΌ ΠΊ цСлочислСнному числу uint32. Π˜Ρ‚ΠΎΠ³ΠΎ 32 Π±ΠΈΡ‚Π°.
// расчСт простой: Π³ΠΎΠ΄ 12 Π±ΠΈΡ‚, мСсяц 4 Π±ΠΈΡ‚Π°, дСнь 5 Π±ΠΈΡ‚ ΠΈ Ρ‚.Π΄. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Π² Π°ΠΊΠΊΡƒΡ€Π°Ρ‚ умСщаСмся Π² 32 Π±ΠΈΡ‚Π° ΠΈΠ»ΠΈ 4 Π±Π°ΠΉΡ‚Π°.
date := uint32(year<<20) | uint32(month<<16) | uint32(day<<11) | uint32(hour<<6) | uint32(minute)

// Π² Ρ†ΠΈΠΊΠ»Π΅ ΠΊΠΎΠ΄ΠΈΡ€ΡƒΠ΅ΠΌ Π±Π°ΠΉΡ‚Ρ‹ Π² ASCII. 1 Π·Π½Π°ΠΊ это ΡˆΠ΅ΡΡ‚ΡŒ Π±ΠΈΡ‚. Π˜Ρ‚ΠΎΠ³ΠΎ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΡˆΠ΅ΡΡ‚ΡŒ Π·Π½Π°ΠΊΠΎΠ² Π΄Π°Ρ‚Ρ‹ ΠΏΠΎ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ASCII – ΠΏΠ΅Ρ‡Π°Ρ‚Π½Ρ‹Π΅ Π·Π½Π°ΠΊΠΈ.
for n := 0; n < 6; n {
b6Bit = byte(date>>i) & 0x3F
sBuilder.WriteByte(byte8bitToASCII(b6Bit))

}

Π’ΡΡŽ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π½Π° Go ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·ΡƒΡ‡ΠΈΡ‚ΡŒ Π½Π° Github-Π΅

ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²Π»Π΅Π½ΠΈΡ


Π‘ сСриализаторами Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π»ΠΈΡΡŒ, Π΄Π°Π²Π°ΠΉΡ‚Π΅ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΠ΅Ρ€Π΅ΠΉΠ΄Π΅ΠΌ ΠΊ прСдставлСниям.

Для Π½Π°ΡˆΠΈΡ… Ρ†Π΅Π»Π΅ΠΉ Π½ΡƒΠΆΠ½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎ прСдставлСниС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ список ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.

Django REST Framework ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ Ρ†Π΅Π»Ρ‹ΠΉ ряд прСдставлСний, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ прСдставлСниС списка ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°. Π’Π°ΠΊΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ класс ListAPIView.


Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ Π² authentication/views.py:

ΠŸΡ€ΠΈΠ΄ΡƒΠΌΡ‹Π²Π°Π΅ΠΌ ΠΊΠΎΠ΄Ρ‹ доступа

Π›ΡŽΠ΄ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΡ€ΠΈΠ΄ΡƒΠΌΠ°Π»ΠΈ Π΄Π²ΡƒΡ…Ρ„Π°ΠΊΡ‚ΠΎΡ€Π½ΡƒΡŽ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ, ΠΏΠΎ всСй видимости, Ρ€ΡƒΠΊΠΎΠ²ΠΎΠ΄ΡΡ‚Π²ΠΎΠ²Π°Π»ΠΈΡΡŒ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΎΠΌ Β«ΠΎΠ΄Π½Π° Π³ΠΎΠ»ΠΎΠ²Π° Ρ…ΠΎΡ€ΠΎΡˆΠΎ, Π° Π΄Π²Π΅ β€” Π»ΡƒΡ‡ΡˆΠ΅Β». И Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ β€” Π΄Π²Π° пароля Ρ‚ΠΎΡ‡Π½ΠΎ бСзопаснСС ΠΎΠ΄Π½ΠΎΠ³ΠΎ. Но ΠΏΠ°Ρ€ΠΎΠ»ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ отправляСт сайт Π² SMS, нСльзя Π½Π°Π·Π²Π°Ρ‚ΡŒ Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎ Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½Ρ‹ΠΌΠΈ: сообщСниС Ρ‡Π°Ρ‰Π΅ всСго ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚ΠΈΡ‚ΡŒ.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ бСзопасных ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹Ρ… ΠΏΠ°Ρ€ΠΎΠ»Π΅ΠΉ состоит ΠΈΠ· Π΄Π²ΡƒΡ… этапов:

  1. ΠŸΠ΅Ρ€Π²ΠΈΡ‡Π½Π°Ρ настройка β€” Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π΄Π²ΡƒΡ…Ρ„Π°ΠΊΡ‚ΠΎΡ€Π½ΠΎΠΉ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ.
  2. ИспользованиС пароля β€” нСпосрСдствСнный Π²Π²ΠΎΠ΄ ΠΊΠΎΠ΄Π° ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ.

Π’ Ρ‚Π°ΠΊΠΎΠΌ случаС ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ прилоТСния, доступного Π½Π° любом устройствС, смоТСт Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ΄Ρ‹ Π² соотвСтствии со всСми стандартами.

ΠŸΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½Π°Ρ настройка прилоТСния Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² ΠΎΠ±ΠΌΠ΅Π½Π΅ сСкрСтным ΠΊΠ»ΡŽΡ‡ΠΎΠΌ ΠΌΠ΅ΠΆΠ΄Ρƒ сСрвСром ΠΈ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ. Π—Π°Ρ‚Π΅ΠΌ этот сСкрСтный ΠΊΠ»ΡŽΡ‡ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π½Π° устройствС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ΄ΠΏΠΈΡΠ°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ извСстны ΠΈ сСрвСру, ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ. Π­Ρ‚ΠΎΡ‚ ΠΊΠ»ΡŽΡ‡ ΠΈ слуТит Π³Π»Π°Π²Π½Ρ‹ΠΌ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ личности ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΏΡ€ΠΈ Π²Π²ΠΎΠ΄Π΅ пароля Π½Π° сСрвСрС.

На самом Π΄Π΅Π»Π΅ вСсь сСкрСт β€” ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΈΠ· случайных символов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ Base32. Π‘ΡƒΠΌΠΌΠ°Ρ€Π½ΠΎ ΠΎΠ½ΠΈ Π·Π°Π½ΠΈΠΌΠ°ΡŽΡ‚ Π½Π΅ мСньшС 128 Π±ΠΈΡ‚, Π° Ρ‡Π°Ρ‰Π΅ ΠΈ всС 190 Π±ΠΈΡ‚. Π­Ρ‚Ρƒ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΈ Π²ΠΈΠ΄ΠΈΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΊΠ°ΠΊ тСкст ΠΈΠ»ΠΈ QR-ΠΊΠΎΠ΄.

Π’Π°ΠΊ выглядит ΠΊΠΎΠ΄ QR для ΠΎΠ±ΠΌΠ΅Π½Π° сСкрСтом
Π’Π°ΠΊ выглядит ΠΊΠΎΠ΄ QR для ΠΎΠ±ΠΌΠ΅Π½Π° сСкрСтом

Как ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ создаСт ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹Π΅ ΠΊΠΎΠ΄Ρ‹? ВсС просто: ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠ»ΡŽΡ‡Π° Ρ…Π΅ΡˆΠΈΡ€ΡƒΠ΅Ρ‚ ΠΊΠ°ΠΊΠΎΠ΅-Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ρ‡Π°Ρ‰Π΅ всСго число, Π±Π΅Ρ€Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ²ΡˆΠ΅Π³ΠΎΡΡ Ρ…Π΅ΡˆΠ° ΠΈ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ Π² Π²ΠΈΠ΄Π΅ числа ΠΈΠ· ΡˆΠ΅ΡΡ‚ΠΈ ΠΈΠ»ΠΈ восьми Ρ†ΠΈΡ„Ρ€.

Π‘ самого Π½Π°Ρ‡Π°Π»Π° для этого числа Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ использовали простой счСтчик Π²Ρ…ΠΎΠ΄ΠΎΠ². Π‘Π΅Ρ€Π²Π΅Ρ€ считал количСство Ρ€Π°Π·, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Ρ‚Ρ‹ Π·Π°Ρ…ΠΎΠ΄ΠΈΠ», Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½Π° сайт, Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ Π±Ρ‹Π»ΠΎ извСстно, сколько Ρ€Π°Π· Ρ‚Ρ‹ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π» ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹ΠΉ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ. ИмСнно это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ использовалось для создания ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π΄Π°Π²Π°ΠΉ ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ ΠΏΠΎΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΊΠΎΠ΄ для Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ. Для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° прСдставим, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Ρ€Π΅ΡˆΠΈΠ»ΠΈ прямо Π² Новый Π³ΠΎΠ΄ ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΠΎΡ‚ΠΎΠ³Ρ€Π°Ρ„ΠΈΡŽ красивого Ρ„Π΅ΠΉΠ΅Ρ€Π²Π΅Ρ€ΠΊΠ° ΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ, Π½ΡƒΠΆΠ½ΠΎ Π²ΠΎΠΉΡ‚ΠΈ Π² свой Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚, Π° Π·Π½Π°Ρ‡ΠΈΡ‚, Π½Π°ΠΌ Π½Π΅ ΠΎΠ±ΠΎΠΉΡ‚ΠΈΡΡŒ Π±Π΅Π· ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ пароля.

Π’ΠΎΠ·ΡŒΠΌΠ΅ΠΌ врСмя празднования Нового Π³ΠΎΠ΄Π° Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ UNIX (1577811600000) ΠΈ посчитаСм порядковый Π½ΠΎΠΌΠ΅Ρ€ нашСго пароля: ΠΏΠΎΠ΄Π΅Π»ΠΈΠΌ Π½Π° 30 сСкунд β€” 52593720. Π’ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡΡ нашим сСкрСтом ΠΈ вычислим Ρ…Π΅Ρˆ β€” ΠΏΠΎ стандарту RFC 6238 это функция SHA-1:

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ бСзопасности

Π₯отя Π²Π²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ²
ΠΏΡ‹Ρ‚Π°ΡŽΡ‚ΡΡ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ бСзопасности Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π½Π° основС cookies, ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΎΡ‚ Π½ΠΈΡ… Π½Π΅ ΠΈΠ·Π±Π°Π²ΠΈΡ‚ΡŒΡΡ.

Π‘ΠΎΡ…Ρ€Π°Π½Π΅Π½Π½Ρ‹Π΅ Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅ Ρ‚ΠΎΠΊΠ΅Π½Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ уязвимы для Π°Ρ‚Π°ΠΊ XSS, Ссли ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ позволяСт Π²Π½Π΅Π΄Ρ€ΡΡ‚ΡŒ внСшниС сцСнарии JavaScript.

Π’ΠΎΠΊΠ΅Π½ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ состояния ΠΈ Ссли ΠΎΠ½ установлСн снаруТи, Ρ‚ΠΎ Π΅Π³ΠΎ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚ΠΎΠ·Π²Π°Ρ‚ΡŒ
Π΄ΠΎ истСчСния срока ΠΆΠΈΠ·Π½ΠΈ. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Π²Π°ΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ ΠΈΠΌΠ΅Π» ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ срок
годности.

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ использования Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ²

Как ΠΈ с любой Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠ΅ΠΉ, Π² Ρ€Π°Π±ΠΎΡ‚Π΅ с Ρ‚ΠΎΠΊΠ΅Π½Π°ΠΌΠΈ Π΅ΡΡ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ограничСния ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹. Π˜Ρ… Π½Π°Π΄ΠΎ ΠΎΡΠΎΠ·Π½Π°Π²Π°Ρ‚ΡŒ ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ с JWT ΠΏΡ€ΠΈ использовании Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ…. Π― ΡƒΠΆΠ΅ ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π», Ρ‡Ρ‚ΠΎ Ρ‚ΠΎΠΊΠ΅Π½ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΎΠ²Π΅Ρ€Π΅Π½ рСсурсным сСрвСром нСзависимо Π½ΠΈ ΠΎΡ‚ Ρ‡Π΅Π³ΠΎ, достаточно лишь сСкрСтной строки.

Но ΠΎΡ‚ΡΡŽΠ΄Π° слСдуСт ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°: Ссли Π²Ρ‹Π΄Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ Π½ΠΎΠ²ΡƒΡŽ ΠΏΠ°Ρ€Ρƒ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ², Π° старая ΠΏΠ°Ρ€Π° Π΅Ρ‰Π΅ Π²Π°Π»ΠΈΠ΄Π½Π°, Ρ‚ΠΎ срСдств Π΅Π΅ Π·Π°ΡΠΊΡΠΏΠ°ΠΉΡ€ΠΈΡ‚ΡŒ Π½Π΅Ρ‚.

Π’Π΅Π΄ΡŒ сам ΠΏΠΎ сСбС Ρ‚ΠΎΠΊΠ΅Π½ β€” это строка, которая Π½ΠΈΠ³Π΄Π΅ Π½Π΅ хранится. Пока ΠΎΠ½ Π²Π°Π»ΠΈΠ΄Π½Ρ‹ΠΉ, ΠΈΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ. Π’ ΠΈΡ‚ΠΎΠ³Π΅ ΡŽΠ·Π΅Ρ€ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π²Ρ‚ΠΎΡ€ΡƒΡŽ ΠΏΠ°Ρ€Ρƒ, Ρ‚Ρ€Π΅Ρ‚ΡŒΡŽ, Ρ‡Π΅Ρ‚Π²Π΅Ρ€Ρ‚ΡƒΡŽ β€” Π° ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠ΅ Π΅Ρ‰Π΅ Π±ΡƒΠ΄ΡƒΡ‚ работоспособны.

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Ρ‚ΠΎΠΊΠ΅Π½Π°

Для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Ρ‚ΠΎΠΊΠ΅Π½Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡ€ΠΎΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚Ρƒ ΠΆΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ.

Π‘Π΅Ρ€Π΅ΠΌ склСйку Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π΄Π°Π½Π½Ρ‹Π΅, ΠΊΠΎΠ΄ΠΈΡ€ΡƒΠ΅ΠΌ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° HMAC-SHA256 ΠΈ нашСго ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½ΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π°. А Π΄Π°Π»Π΅Π΅ Π±Π΅Ρ€Π΅ΠΌ сигнатуру с Ρ‚ΠΎΠΊΠ΅Π½Π° ΠΈ свСряСм с Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ кодирования. Если Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‚ – Π·Π½Π°Ρ‡ΠΈΡ‚ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½Ρ‹ ΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ ΡƒΠ²Π΅Ρ€Π΅Π½Π½Ρ‹ΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ Π½Π΅ Π±Ρ‹Π»ΠΈ ΠΏΠΎΠ΄ΠΌΠ΅Π½Π΅Π½Ρ‹.

Π Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΠΎΠ²Ρ‹Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ с использованиСм jwt

БСгодня Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ… приходится Ρ€Π΅ΡˆΠ°Ρ‚ΡŒ Π·Π°Π΄Π°Ρ‡ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ выходят Π·Π° Ρ€Π°ΠΌΠΊΠΈ описываСмых Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ², Π½ΠΎ ΠΏΡ€ΠΈ этом ΠΎΠ½ΠΈ Π±Π°Π·ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π½Π° ΠΈΡ… использовании. ΠŸΠ΅Ρ€Π²Π°Ρ подобная Π·Π°Π΄Π°Ρ‡Π° β€” lockout-ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ. Он ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ послС Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Π±Π΅Π·ΡƒΡΠΏΠ΅ΡˆΠ½Ρ‹Ρ… ΠΏΠΎΠΏΡ‹Ρ‚ΠΎΠΊ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ.

Π― Π½Π΅ Π±ΡƒΠ΄Ρƒ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ ΠΎΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒΡΡ Π½Π° этой Π·Π°Π΄Π°Ρ‡Π΅, ΠΎΠ½Π° достаточно простая. Если ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ нСсколько Ρ€Π°Π· подряд Π²Π²Π΅Π» ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Π΅ имя ΠΈΠ»ΠΈ email, Π½ΠΎ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ, Π½Π°Π΄ΠΎ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ этого ΡŽΠ·Π΅Ρ€Π° Π½Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ врСмя. Для этого Π½Π° сСрвСрС Π½ΡƒΠΆΠ½ΠΎ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ, допустим, Π² Π±Π°Π·Ρƒ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½ΠΎΠ΅ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ количСство Π±Π΅Π·ΡƒΡΠΏΠ΅ΡˆΠ½Ρ‹Ρ… ΠΏΠΎΠΏΡ‹Ρ‚ΠΎΠΊ ΠΈ Π·Π°Π΄Π°Ρ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ доступа Π² случаС ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ΅Π½ΠΈΠΈ этого показатСля.

Π‘ΠΎΠ»Π΅Π΅ интСрСсныС Π·Π°Π΄Π°Ρ‡ΠΈ β€” Logout ΠΈ Only one active device, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π² ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ΅ связаны ΠΌΠ΅ΠΆΠ΄Ρƒ собой.

Logout ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ послС наТатия ΠΊΠ½ΠΎΠΏΠΊΠΈ Π»ΠΎΠ³Π°ΡƒΡ‚Π° Π²ΠΎ Ρ„Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ Π½Π°Π΄ΠΎ с ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ Π²Ρ‹Ρ…ΠΎΠ΄Π° Π΅Ρ‰Π΅ ΠΈ ΠΈΠ½Π²Π°Π»ΠΈΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ сами Ρ‚ΠΎΠΊΠ΅Π½Ρ‹, ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΈΡ… Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ.

РаскрытиС ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ Ρ‚ΠΎΠΊΠ΅Π½Π΅

Π­Ρ‚Π° Π°Ρ‚Π°ΠΊΠ° происходит, ΠΊΠΎΠ³Π΄Π° Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ доступ ΠΊ Ρ‚ΠΎΠΊΠ΅Π½Ρƒ (ΠΈΠ»ΠΈ ΠΊ Π½Π°Π±ΠΎΡ€Ρƒ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ²) ΠΈ ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅Ρ‚ ΡΠΎΡ…Ρ€Π°Π½Π΅Π½Π½ΡƒΡŽ Π² Π½Π΅ΠΌ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ (информация ΠΎ Ρ‚ΠΎΠΊΠ΅Π½Π΅ JWT кодируСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ base64) для получСния ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ систСмС. Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ‚Π°ΠΊΠΎΠΉ ΠΊΠ°ΠΊ, Ρ€ΠΎΠ»ΠΈ бСзопасности, Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Π²Ρ…ΠΎΠ΄Π° Π² систСму ΠΈ Ρ‚.Π΄.

Бпособ Π·Π°Ρ‰ΠΈΡ‚Ρ‹ достаточно ΠΎΡ‡Π΅Π²ΠΈΠ΄Π΅Π½ ΠΈ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΠΈ Ρ‚ΠΎΠΊΠ΅Π½Π°. Π’Π°ΠΊΠΆΠ΅ Π²Π°ΠΆΠ½ΠΎ Π·Π°Ρ‰ΠΈΡ‚ΠΈΡ‚ΡŒ Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΎΡ‚ Π°Ρ‚Π°ΠΊ с использованиСм ΠΊΡ€ΠΈΠΏΡ‚ΠΎΠ°Π½Π°Π»ΠΈΠ·Π°. Для достиТСния всСх этих Ρ†Π΅Π»Π΅ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ AES-GCM, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ обСспСчиваСт Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΠ΅ с ассоциированными Π΄Π°Π½Π½Ρ‹ΠΌΠΈ (Authenticated Encryption with Associated Data – AEAD).

ΠŸΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ² AEAD обСспСчиваСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ симмСтричного Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΡ. Π Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ этого ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π° Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Ρ‹ ΠΎΡ‚ Π°Π΄Π°ΠΏΡ‚ΠΈΠ²Π½Ρ‹Ρ… Π°Ρ‚Π°ΠΊ Π½Π° основС ΠΏΠΎΠ΄ΠΎΠ±Ρ€Π°Π½Π½ΠΎΠ³ΠΎ ΡˆΠΈΡ„Ρ€Ρ‚Π΅ΠΊΡΡ‚Π°. ΠŸΡ€ΠΈ ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ тСкста ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ связанныС Π΄Π°Π½Π½Ρ‹Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹, Π½ΠΎ Π½Π΅ Π·Π°ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½Ρ‹.

Π’ΠΎ Π΅ΡΡ‚ΡŒ ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΠ΅ с ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ обСспСчиваСт ΠΏΠΎΠ΄Π»ΠΈΠ½Π½ΠΎΡΡ‚ΡŒ ΠΈ Ρ†Π΅Π»ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Ρ…, Π½ΠΎ Π½Π΅ ΠΈΡ… ΡΠ΅ΠΊΡ€Π΅Ρ‚Π½ΠΎΡΡ‚ΡŒ.

Однако Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΠ΅ добавляСтся Π² основном для сокрытия Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ, Π½ΠΎ ΠΎΡ‡Π΅Π½ΡŒ Π²Π°ΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠΉ Π·Π°Ρ‰ΠΈΡ‚ΠΎΠΉ ΠΎΡ‚ ΠΏΠΎΠ΄Π΄Π΅Π»ΠΊΠΈ Ρ‚ΠΎΠΊΠ΅Π½Π° JWT являСтся подпись, поэтому подпись Ρ‚ΠΎΠΊΠ΅Π½Π° ΠΈ Π΅Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ всСгда ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Ρ‹.

РСализация ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ подлинности с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ json web token

Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΠΎΠΉΠ΄Π΅ΠΌ дальшС ΠΈ создадим наш ΠΏΡ€ΠΎΠ΅ΠΊΡ‚.

ΠŸΠ΅Ρ€Π΅ΠΉΠ΄ΠΈΡ‚Π΅ Π² ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹:

Π‘Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Ρ‹


Для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ работоспособности API Π½ΡƒΠΆΠ½ΠΎ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π½Π° AJAX запросы. Π‘Π°ΠΌΡ‹ΠΉ простой способ это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ β€” ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π² нашСй систСмС.

ΠŸΠ΅Ρ€Π²ΠΎΠ΅, Ρ‡Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ, это ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. Π’Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ ΠΈ слСдуйтС инструкциям Π½Π° экранС:

Π‘ΠΈΠ³Π½Π°Ρ‚ΡƒΡ€Π°

ПослСдняя Ρ‡Π°ΡΡ‚ΡŒ Ρ‚ΠΎΠΊΠ΅Π½Π° – Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ваТная. Π£ нас это E4FNMef6tkjIsf7paNrWZnB88c3WyIfjONzAeEd4wF0

Как Π²Ρ‹ ΡƒΠΆΠ΅ ΠΌΠΎΠ³Π»ΠΈ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ – ΠΏΠ΅Ρ€Π²Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ практичСски Π² ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠΌ Π²ΠΈΠ΄Π΅ ΠΈ Ρ€Π°ΡΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ… ΠΌΠΎΠΆΠ΅Ρ‚ любой. Но ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ… Π½Π΅Ρ‚ нСобходимости. ЦСль Ρ‚ΠΎΠΊΠ΅Π½Π° – ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€Π΄ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ эти Π΄Π°Π½Π½Ρ‹Π΅ Π½Π΅ Π±Ρ‹Π»ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Ρ‹. Π’ΠΎΡ‚ для этих Ρ†Π΅Π»Π΅ΠΉ ΠΈ выступаСт сигнатура. И Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΅Ρ‘ ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½ΡƒΠΆΠ΅Π½ ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡.

Она получаСтся ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ django прилоТСния

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π΄Π°Π²Π°ΠΉΡ‚Π΅ создадим ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Django для хранСния Π² Π½Π΅ΠΌ прСдставлСний ΠΈ сСриализаторов:

$ python manage.py startapp authentication

Π”ΠΎΠ±Π°Π²ΠΈΠΌ ‘authentication’ Π² наш INSTALLED_APPS (Π² django_angular_token_auth/settings.py like so):

INSTALLED_APPS = (
	...,
	'rest_framework',
	'authentication',
)


Как ΠΏΡ€ΠΈΠ²ΠΈΠ»ΠΎ послС создания прилоТСния Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ, для создания ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ Π² Π‘Π”. Но ΠΌΡ‹ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ собствСнныС ΠΌΠΎΠ΄Π΅Π»ΠΈ, поэтому ΠΎΠ± этом Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π±Π΅ΡΠΏΠΎΠΊΠΎΠΈΡ‚ΡŒΡΡ.

БообраТСния ΠΏΠΎ ΠΏΠΎΠ²ΠΎΠ΄Ρƒ использования jwt

Π”Π°ΠΆΠ΅ Ссли Ρ‚ΠΎΠΊΠ΅Π½ JWT прост Π² использовании ΠΈ позволяСт ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ сСрвисы (Π² основном REST) Π±Π΅Π· сохранСния состояния (stateless), Ρ‚Π°ΠΊΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ Π½Π΅ для всСх ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΎ поставляСтся с Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ ΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΊΠ°ΠΌΠΈ, ΠΊΠ°ΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, вопрос хранСния Ρ‚ΠΎΠΊΠ΅Π½Π°.

Если ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ stateless, Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°ΡΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ использования Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмы сСссий, прСдоставляСмой всСми Π²Π΅Π±-ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°ΠΌΠΈ. Однако для stateless ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ JWT – это Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚, Ссли ΠΎΠ½ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½.

Π‘Ρ€Π°Π²Π½Π΅Π½ΠΈΠ΅ сСссий ΠΈ jwt

НавСрняка ΠΊΡ‚ΠΎ-Ρ‚ΠΎ скаТСт: Β«Π£Ρ€Π°, Π²Ρ‹ ΠΏΠ΅Ρ€Π΅ΠΎΡ‚ΠΊΡ€Ρ‹Π»ΠΈ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ сСссий», ΠΈ Π² этом Π΅ΡΡ‚ΡŒ доля ΠΏΡ€Π°Π²Π΄Ρ‹. Π’ΠΎΠΊΠ΅Π½ Π½ΡƒΠΆΠ΅Π½ для подтвСрТдСния Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. А ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ сСсии β€” это ΠΏΡ€ΠΈΠ·Π½Π°ΠΊ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠΉ сСссии: находится Π»ΠΈ сСйчас ΡŽΠ·Π΅Ρ€ Π² систСмС, ΠΌΠΎΠΆΠ΅Ρ‚ Π»ΠΈ ΠΎΠ½ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Π½Π΅ΠΉ, ΠΈΠ»ΠΈ сСссия Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π°.

Π’ ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚Π΅ Π²Π°ΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΏΠ°ΡΡ‚ΡŒΡΡ такая Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ саркастичСская ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠ°:

Π₯Ρ€Π°Π½Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ² Π½Π° сторонС ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°

Если ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ…Ρ€Π°Π½ΠΈΡ‚ Ρ‚ΠΎΠΊΠ΅Π½ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ ΠΎΠ΄Π½Π° ΠΈΠ»ΠΈ нСсколько ΠΈΠ· ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… ситуаций:

Для прСдотвращСния Π°Ρ‚Π°ΠΊΠΈ:

  1. Π₯Ρ€Π°Π½ΠΈΡ‚ΡŒ Ρ‚ΠΎΠΊΠ΅Π½ Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ sessionStorage.
  2. Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Authorization, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ схСму Bearer. Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:
    Authorization: Bearer <token>
  3. Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ fingerprint ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΊ Ρ‚ΠΎΠΊΠ΅Π½Ρƒ.

Бохраняя Ρ‚ΠΎΠΊΠ΅Π½ Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅ sessionStorage, ΠΎΠ½ прСдоставляСт Ρ‚ΠΎΠΊΠ΅Π½ для ΠΊΡ€Π°ΠΆΠΈ Π² случаС XSS. Однако fingerprint, Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π½Ρ‹ΠΉ Π² Ρ‚ΠΎΠΊΠ΅Π½, ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ΅ использованиС ΡƒΠΊΡ€Π°Π΄Π΅Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΎΠΊΠ΅Π½Π° Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊΠΎΠΌ Π½Π° Π΅Π³ΠΎ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π΅. Π§Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΡŒ максимум областСй использования для Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊΠ°, Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ ΠŸΠΎΠ»ΠΈΡ‚ΠΈΠΊΡƒ бСзопасности содСрТимого Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π° (Content Security Policy), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒ контСкст выполнСния.

ΠžΡΡ‚Π°Π΅Ρ‚ΡΡ случай, ΠΊΠΎΠ³Π΄Π° Π·Π»ΠΎΡƒΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΈΠΊ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ контСкст просмотра ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π² качСствС прокси-сСрвСра, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ†Π΅Π»Π΅Π²ΠΎΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π΅Π· Π»Π΅Π³ΠΈΡ‚ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, Π½ΠΎ Content Security Policy ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ связь с Π½Π΅ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄Π΅Π½Π½Ρ‹ΠΌΠΈ Π΄ΠΎΠΌΠ΅Π½Π°ΠΌΠΈ.

Π’Π°ΠΊΠΆΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ слуТбу Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ‚ΠΎΠΊΠ΅Π½ выдавался Π²Π½ΡƒΡ‚Ρ€ΠΈ Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° cookie, Π½ΠΎ Π² этом случаС Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ CSRF.

Π¨Π°Π±Π»ΠΎΠ½Ρ‹

Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ простой шаблон, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ нашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅.


Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ Ρ„Π°ΠΉΠ» с ΠΈΠΌΠ΅Π½Π΅ΠΌ templates/index.html ΠΈ Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ Π² Π½Π΅Π³ΠΎ:

Π’ дальнСйшСм ΠΌΡ‹ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ angular ΠΊΠΎΠ΄ Π² Π΄Π°Π½Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ».

Π¨Π°Π³ 2. полСзная Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ°

Π’ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ JSON Π²Π΅Π±-Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ² (payload) хранится информация ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ сСрвСр Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ сСрвСру прилоТСния. Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ прСдусматриваСт нСсколько Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… для заполнСния слуТСбных ΠΏΠΎΠ»Π΅ΠΉ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

  • exp – срок окончания дСйствия Ρ‚ΠΎΠΊΠ΅Π½Π°;
  • nbf – врСмя Π½Π°Ρ‡Π°Π»Π° дСйствия Ρ‚ΠΎΠΊΠ΅Π½Π°;
  • sub – ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ.

Если интСрСсно, ΠΏΠΎΡ‡ΠΈΡ‚Π°ΠΉΡ‚Π΅ Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ΅ описаниС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π² Π’ΠΈΠΊΠΈΠΏΠ΅Π΄ΠΈΠΈ.

Помимо стандартных ΠΊΠ»ΡŽΡ‡Π΅ΠΉ, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π»ΡŽΠ±Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅:

Шаг 3. подпись

Подпись Ρ‚ΠΎΠΊΠ΅Π½Π° вычисляСтся Π½Π° основС Π΅Π³ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° ΠΈ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΏΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ схСмС (псСвдокод):

data = base64urlEncode(header)   "."   base64urlEncode(payload)
hashedData = hash(data, secret)
signature = base64urlEncode(hashedData)

Π Π°Π·Π±Π΅Ρ€Π΅ΠΌ ΠΏΠΎ шагам:

// header
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

// payload
eyJ1c2VySWQiOiJiMDhmODZhZi0zNWRhLTQ4ZjItOGZhYi1jZWYzOTA0NjYwYmQifQ
// signature
-xN_h82PHVTCMA9vdoHrcZxH-x5mb11y1537t3rGzcM

Π¨Π°Π³ 4. cΠ±ΠΎΡ€ΠΊΠ° jwt

Π£ нас ΡƒΠΆΠ΅ Π΅ΡΡ‚ΡŒ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ Π±Π»ΠΎΠΊΠΈ для создания Ρ‚ΠΎΠΊΠ΅Π½Π°:

  • Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ с ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° Ρ…Π΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ;
  • полСзная Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ° с ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ;
  • сгСнСрированная подпись.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ ΠΈΠ· Π½ΠΈΡ… ΠΏΠΎΠ»Π½ΠΎΡ†Π΅Π½Π½Ρ‹ΠΉ Π²Π΅Π±-Ρ‚ΠΎΠΊΠ΅Π½ ΠΏΠΎ ΡƒΠΆΠ΅ Π·Π½Π°ΠΊΠΎΠΌΠΎΠΉ схСмС:

header.payload.signature

Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈ полСзная Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊΠΎΠ΄ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π² Base64URL, Π° подпись ΡƒΠΆΠ΅ Π² ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΌ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅:

// JWT
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1nij9.eyJ1c2VySWQiOiJiMDhmODZhZi0zNWRhltq4zjitogzhyi1jzwyzota0njywymqifq.-xN_h82PHVTCMA9vdoHrcZxH-x5mb11y1537t3rGzcM

Π­Ρ‚ΠΎΡ‚ Ρ‚ΠΎΠΊΠ΅Π½ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ ΠΎΡ‚ сСрвСра Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΈ запросах ΠΊ сСрвСру прилоТСния.

Π­Ρ‚ΠΎ stateless-ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ

Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ cookie-ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π°, Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ с Ρ‚ΠΎΠΊΠ΅Π½Π°ΠΌΠΈ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ состояния. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π½Π΅ сохраняСт Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ
ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΡ… Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ Π½Π° сСрвСрС. Π‘Π΅Ρ€Π²Π΅Ρ€ ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π·Π°
созданиС ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ², Ρ‡Ρ‚ΠΎ позволяСт Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΡƒΠ΅ΠΌΡ‹Π΅
Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ.

Π­Ρ‚ΠΎ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ процСсс

Если Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ Ρ„Π°ΠΉΠ»Ρ‹
cookie для Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ, Π²Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π½ΠΈΡ‡Π΅Π³ΠΎ большС Ρ€Π°Π·Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ для
добавлСния ΠΈΡ… Π² запросы. Π‘Ρ€Π°ΡƒΠ·Π΅Ρ€ позаботится ΠΎΠ± ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΈ
автоматичСски Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ cookie для всСх запросов.

Π₯отя этот Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ процСсс ΠΎΠ±Π»Π΅Π³Ρ‡Π°Π΅Ρ‚ Ρ‚Ρ€ΡƒΠ΄ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ², здСсь Π΅ΡΡ‚ΡŒ нСсколько нСдостатков. НапримСр, Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ запросы Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ, Π½ΠΎ ΠΏΡ€ΠΈ Ρ‚Π°ΠΊΠΎΠΌ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π΅ ΠΊΡƒΠΊΠΈ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒΡΡ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ запросС.

ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΏΡ€ΠΈ CSRF-Π°Ρ‚Π°ΠΊΠ΅
Π·Π»ΠΎΠ΄Π΅ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ этим ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ запросы с cookie Π½Π° ΠΌΠΎΡˆΠ΅Π½Π½ΠΈΡ‡Π΅ΡΠΊΠΈΠ΅ сайты.

Π―Π²Π½ΠΎΠ΅ Π°Π½Π½ΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ‚ΠΎΠΊΠ΅Π½Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ‚ΠΎΠΊΠ΅Π½ становится Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послС истСчСния срока Π΅Π³ΠΎ дСйствия, Ρƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π½Π΅Ρ‚ встроСнной Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰Π΅ΠΉ явно ΠΎΡ‚ΠΌΠ΅Π½ΠΈΡ‚ΡŒ дСйствиС Ρ‚ΠΎΠΊΠ΅Π½Π°. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π² случаС ΠΊΡ€Π°ΠΆΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ сам ΠΎΡ‚ΠΎΠ·Π²Π°Ρ‚ΡŒ Ρ‚ΠΎΠΊΠ΅Π½ ΠΈ Π·Π°Ρ‚Π΅ΠΌ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π°Ρ‚Π°ΠΊΡƒΡŽΡ‰Π΅Π³ΠΎ.

Одним ΠΈΠ· способов Π·Π°Ρ‰ΠΈΡ‚Ρ‹ являСтся Π²Π½Π΅Π΄Ρ€Π΅Π½ΠΈΠ΅ Ρ‡Π΅Ρ€Π½ΠΎΠ³ΠΎ списка Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΈΠ³ΠΎΠ΄Π΅Π½ для ΠΈΠΌΠΈΡ‚Π°Ρ†ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Β«Π²Ρ‹Ρ…ΠΎΠ΄ ΠΈΠ· систСмы», ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ Π² Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмС сСансов.

Π’ Ρ‡Π΅Ρ€Π½ΠΎΠΌ спискС Π±ΡƒΠ΄Π΅Ρ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒΡΡ сборник (Π² ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²ΠΊΠ΅ SHA-256 Π² HEX) Ρ‚ΠΎΠΊΠ΅Π½Π° с Π΄Π°Ρ‚ΠΎΠΉ аннулирования, которая Π΄ΠΎΠ»ΠΆΠ½Π° ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°Ρ‚ΡŒ срок дСйствия Π²Ρ‹Π΄Π°Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΎΠΊΠ΅Π½Π°.

Когда ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Ρ…ΠΎΡ‡Π΅Ρ‚ Β«Π²Ρ‹ΠΉΡ‚ΠΈΒ», ΠΎΠ½ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΡƒΡŽ слуТбу, которая добавляСт прСдоставлСнный Ρ‚ΠΎΠΊΠ΅Π½ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π² Ρ‡Π΅Ρ€Π½Ρ‹ΠΉ список, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎΠΌΡƒ Π°Π½Π½ΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ Ρ‚ΠΎΠΊΠ΅Π½Π° для дальнСйшСго использования Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ:

Π₯Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Ρ‡Π΅Ρ€Π½ΠΎΠ³ΠΎ списка:Для Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ хранСния Ρ‡Π΅Ρ€Π½ΠΎΠ³ΠΎ списка Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π±Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ… со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ структурой:

create table if not exists revoked_token(jwt_token_digest varchar(255) primary key,
revokation_date timestamp default now());

Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ аннулированиями Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ²:

// ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΡ‚ΠΊΠ°Ρ‚Π° Ρ‚ΠΎΠΊΠ΅Π½Π° (logout).
// Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π‘Π”, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚ΡŒ нСскольким экзСмплярам ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ
// ΠΎΡ‚ΠΎΠ·Π²Π°Π½Π½Ρ‹ΠΉ Ρ‚ΠΎΠΊΠ΅Π½ ΠΈ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚ΡŒ очистку Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠΉ Π‘Π”.
public class TokenRevoker {

 // ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ Π‘Π”
 @Resource("jdbc/storeDS")
 private DataSource storeDS;

 // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° являСтся Π»ΠΈ Ρ‚ΠΎΠΊΠ΅Π½ ΠΎΡ‚ΠΎΠ·Π²Π°Π½Π½Ρ‹ΠΌ
 public boolean isTokenRevoked(String jwtInHex) throws Exception {
     boolean tokenIsPresent = false;
     if (jwtInHex != null && !jwtInHex.trim().isEmpty()) {
         // Π”Π΅ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ‚ΠΎΠΊΠ΅Π½Π°
         byte[] cipheredToken = DatatypeConverter.parseHexBinary(jwtInHex);

         // ВычислСниС SHA256 ΠΎΡ‚ Ρ‚ΠΎΠΊΠ΅Π½Π°
         MessageDigest digest = MessageDigest.getInstance("SHA-256");
         byte[] cipheredTokenDigest = digest.digest(cipheredToken);
         String jwtTokenDigestInHex = DatatypeConverter.printHexBinary(cipheredTokenDigest);

         // Поиск Ρ‚ΠΎΠΊΠ΅Π½Π° Π² Π‘Π”
         try (Connection con = this.storeDS.getConnection()) {
             String query = "select jwt_token_digest from revoked_token where jwt_token_digest = ?";
             try (PreparedStatement pStatement = con.prepareStatement(query)) {
                 pStatement.setString(1, jwtTokenDigestInHex);
                 try (ResultSet rSet = pStatement.executeQuery()) {
                     tokenIsPresent = rSet.next();
                 }
             }
         }
     }

     return tokenIsPresent;
 }

// Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ Π² HEX Ρ‚ΠΎΠΊΠ΅Π½Π° Π² Ρ‚Π°Π±Π»ΠΈΡ†Π° ΠΎΡ‚ΠΎΠ·Π²Π°Π½Π½Ρ‹Ρ… Ρ‚ΠΎΠΊΠ΅Π½ΠΎΠ²
public void revokeToken(String jwtInHex) throws Exception {
     if (jwtInHex != null && !jwtInHex.trim().isEmpty()) {
         // Π”Π΅ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ‚ΠΎΠΊΠ΅Π½Π°
         byte[] cipheredToken = DatatypeConverter.parseHexBinary(jwtInHex);

         // ВычислСниС SHA256 ΠΎΡ‚ Ρ‚ΠΎΠΊΠ΅Π½Π°
         MessageDigest digest = MessageDigest.getInstance("SHA-256");
         byte[] cipheredTokenDigest = digest.digest(cipheredToken);
         String jwtTokenDigestInHex = DatatypeConverter.printHexBinary(cipheredTokenDigest);

         // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π° Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Ρ‚ΠΎΠΊΠ΅Π½Π° ΡƒΠΆΠ΅ Π² Π‘Π” ΠΈ занСсСниС Π² Π‘Π” Π²
	   // ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΌ случаС
         if (!this.isTokenRevoked(jwtInHex)) {
             try (Connection con = this.storeDS.getConnection()) {
                 String query = "insert into revoked_token(jwt_token_digest) values(?)";
                 int insertedRecordCount;
                 try (PreparedStatement pStatement = con.prepareStatement(query)) {
                     pStatement.setString(1, jwtTokenDigestInHex);
                     insertedRecordCount = pStatement.executeUpdate();
                 }
                 if (insertedRecordCount != 1) {
                     throw new IllegalStateException("Number of inserted record is invalid,"   " 1 expected but is "   insertedRecordCount);
                 }
             }
         }

     }
 }

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

ΠŸΠΎΠ΄Ρ…ΠΎΠ΄Ρ‹, основанныС Π½Π° Ρ‚ΠΎΠΊΠ΅Π½Π°Ρ… ΠΈ Ρ„Π°ΠΉΠ»Π°Ρ… cookie – Π΄Π²Π° Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… Π² Π²Π΅Π±-прилоТСниях ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ. Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ выяснили, ΠΊΠ°ΠΊ ΠΎΠ½ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚, Π° Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π»ΠΈ ΠΈΡ… особСнности, ΠΏΠ»ΡŽΡΡ‹ ΠΈ минусы.

Ни ΠΎΠ΄ΠΈΠ½ ΠΈΠ· этих ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ²
Π½Π΅ являСтся Π½Π° 100% ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½Ρ‹ΠΌ, ΠΈ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠΌΠ΅Π΅Ρ‚ свои нСдостатки. ΠŸΡ€ΠΈ
Π²Ρ‹Π±ΠΎΡ€Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ стоит ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ трСбованиям ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈ Π΄ΠΎΠΏΠΈΠ»ΠΈΡ‚ΡŒ Π΅Π³ΠΎ, Π° Π½Π΅ ΡΡ‚Ρ€Π΅ΠΌΠΈΡ‚ΡŒΡΡ ΠΊ ΠΈΠ΄Π΅Π°Π»Ρƒ.

Бпасибо за вниманиС!

***

Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Ρ‹:

ΠŸΠΎΡ…ΠΎΠΆΠ΅Π΅:  ΠŸΠΎΡ€Ρ‚Π°Π» "Π–ΠšΠ₯" / МУП ΠœΠžΠ“ΠžΠš РК "Π–Π˜Π›Π‘Π•Π Π’Π˜Π‘ΠšΠ•Π Π§Π¬"

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ

Π’Π°Ρˆ адрСс email Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½. ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ поля ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Ρ‹ *