Skip to main content

āļŠāļēāļĢāļˆāļēāļāļ™āļąāļāđ€āļ‚āļĩāļĒāļ™

āļ—āļļāļāļ„āļ™āļ„āļīāļ”āļ§āđˆāļē āđ€āļĄāļ·āđˆāļ­āđ€āļĢāļēāļ•āđ‰āļ­āļ‡āļāļēāļĢāļŠāļĢāđ‰āļēāļ‡ Web Application āļ‚āļķāđ‰āļ™āļĄāļēāđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰āļšāļĢāļīāļāļēāļĢāļ‚āđ‰āļ­āļĄāļđāļĨāđāļāđˆāļšāļļāļ„āļ„āļĨāļ—āļąāđˆāļ§āđ„āļ› āļ­āļ°āđ„āļĢāļ„āļ·āļ­āļŠāļīāđˆāļ‡āđāļĢāļāļ—āļĩāđˆāđ€āļĢāļēāļ„āļ§āļĢāļ•āđ‰āļ­āļ‡āļ—āļģ āđāļ™āđˆāļ™āļ­āļ™āļ§āđˆāļēāļ„āļģāļ•āļ­āļšāļāđ‡āļ„āļ·āļ­ āļĢāļ°āļšāļš Authentication āļ™āļąāđˆāļ™āđ€āļ­āļ‡


āđāļĨāđ‰āļ§āļĢāļ°āļšāļš Authentication āļĄāļąāļ™āļ„āļ·āļ­āļ­āļ°āđ„āļĢāļāļąāļ™āļĨāđˆāļ°

āļ—āļļāļāļ„āļ™āļ„āļ‡āļˆāļ°āđ€āļ„āļĒ Login āđ€āļ§āļĨāļēāļ—āļĩāđˆāļ•āđ‰āļ­āļ‡āļāļēāļĢāđ€āļ‚āđ‰āļēāđƒāļŠāđ‰āļ‡āļēāļ™ Website āļŦāļĢāļ·āļ­ Application āļāļąāļ™āļĄāļēāļšāđ‰āļēāļ‡āđƒāļŠāđˆāļĄāļąāđ‰āļĒ āļĢāļ°āļšāļšāļāļēāļĢāļĒāļ·āļ™āļĒāļąāļ™āļ•āļąāļ§āļ•āļ™āļ—āļĩāđˆāļˆāļ°āļ„āļ­āļĒāļšāļ­āļ Website āļŦāļĢāļ·āļ­ Application āđ€āļŦāļĨāđˆāļēāļ™āļąāđ‰āļ™āļ§āđˆāļēāđ€āļĢāļēāļ„āļ·āļ­āđƒāļ„āļĢāļ™āļąāđˆāļ™āđāļŦāļĨāļ°āļ„āļ·āļ­āļŠāļīāđˆāļ‡āļ—āļĩāđˆāđ€āļĢāļĩāļĒāļāļ§āđˆāļē āļĢāļ°āļšāļš Authentication

āļ‹āļķāđˆāļ‡āļ„āļ§āļēāļĄāļĒāļēāļāļ‚āļ­āļ‡āļāļēāļĢāļ—āļģāļĢāļ°āļšāļš Authentication āļ„āļ·āļ­

āļāļēāļĢāļ—āļĩāđˆ Web Application āļ™āļąāđ‰āļ™āļĄāļĩāļĢāļđāļ›āđāļšāļšāļāļēāļĢāļŠāļ·āđˆāļ­āļŠāļēāļĢāļ—āļĩāđˆāđ„āļĄāđˆāļĢāļđāđ‰āļˆāļąāļāļˆāļ”āļˆāļģāļ­āļ°āđ„āļĢāđ€āļĨāļĒ āļ—āļģāđƒāļŦāđ‰āļ—āļļāļ Request āļ—āļĩāđˆ User āļŠāđˆāļ‡āđ„āļ›āļĒāļąāļ‡āļĢāļ°āļšāļšāļāđ‡āļˆāļ°āļ•āđ‰āļ­āļ‡āļ–āļđāļāļ•āļĢāļ§āļˆāļŠāļ­āļšāļŠāļīāļ—āļ˜āļīāđŒāđƒāļŦāļĄāđˆāļ—āļļāļāļ„āļĢāļąāđ‰āļ‡ āļ­āļēāļāļēāļĢāđāļšāļšāļ™āļĩāđ‰āļ‚āļ­āļ‡āļĄāļąāļ™āļ–āļđāļāđ€āļĢāļĩāļĒāļāļ§āđˆāļē Stateless āļāļĨāđˆāļēāļ§āļ„āļ·āļ­ āļŦāļĨāļąāļ‡āļˆāļēāļāļ—āļĩāđˆ User āđ„āļ”āđ‰ Login āđ€āļ‚āđ‰āļēāļĄāļēāđƒāļ™āļĢāļ°āļšāļšāđ€āļĢāļĩāļĒāļšāļĢāđ‰āļ­āļĒāđāļĨāđ‰āļ§ āļžāļ­ User āļˆāļ°āļ—āļģāļāļīāļˆāļāļĢāļĢāļĄāļ•āđˆāļ­āđ„āļ› āļĢāļ°āļšāļšāļāđ‡āļˆāļģāđ„āļĄāđˆāđ„āļ”āđ‰āđāļĨāđ‰āļ§āļ§āđˆāļē User āļ„āļ™āļ™āļĩāđ‰āđ€āļžāļīāđˆāļ‡āļˆāļ° Login āđ€āļ‚āđ‰āļēāļĄāļē

āļ–āđ‰āļēāļ­āļĒāđˆāļēāļ‡āļ™āļąāđ‰āļ™ āđ€āļĢāļēāļˆāļ°āļ—āļģāļĒāļąāļ‡āđ„āļ‡āļāļąāļ™āļ”āļĩāļĨāđˆāļ°

āđ€āļĢāļēāļāđ‡āđāļ„āđˆāļ•āđ‰āļ­āļ‡āļŠāđˆāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāđ„āļ›āļšāļ­āļāļĢāļ°āļšāļšāđƒāļ™āļ—āļļāļ āđ† āļāļēāļĢ Request āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰āļĢāļ°āļšāļšāđ„āļĄāđˆāļĨāļ·āļĄāļ§āđˆāļē āļ„āļ™āļ—āļĩāđˆāļŠāđˆāļ‡ Request āļ™āļĩāđ‰āļĄāļēāļ„āļ·āļ­ User āļ„āļ™āļ™āļĩāđ‰āļ™āļ° āļ—āļĩāđˆāđ€āļžāļīāđˆāļ‡ Login āđ€āļ‚āđ‰āļēāļĄāļē āļ‹āļķāđˆāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļĩāđˆāđ€āļĢāļēāļˆāļ°āļŠāđˆāļ‡āđ„āļ›āļšāļ­āļāļĢāļ°āļšāļšāļ™āļąāđ‰āļ™ āđ€āļĢāļēāđ€āļĢāļĩāļĒāļāļ­āļĩāļāļ­āļĒāđˆāļēāļ‡āļ™āļķāļ‡āļ§āđˆāļē Token āđ‚āļ”āļĒāđƒāļ™āļšāļ—āļ„āļ§āļēāļĄāļ™āļĩāđ‰āđ€āļĢāļēāļˆāļ°āļžāļēāļ—āļļāļāļ„āļ™āđ„āļ›āļ—āļģāļ„āļ§āļēāļĄāļĢāļđāđ‰āļˆāļąāļāļāļąāļš Standard Token āļ•āļąāļ§āļ™āļķāļ‡āļ—āļĩāđˆāļŠāļ·āđˆāļ­āļ§āđˆāļē JWT āļŦāļĢāļ·āļ­ JSON Web Tokens

āļ—āļģāđ„āļĄāļ•āđ‰āļ­āļ‡āđ€āļ›āđ‡āļ™ JWT (JSON Web Tokens)

JWT āļĒāđˆāļ­āļĄāļēāļˆāļēāļ JSON Web Tokens āđ€āļ›āđ‡āļ™ Standard Token āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡āļˆāļēāļāļ‚āđ‰āļ­āļĄāļđāļĨāļ‚āļ­āļ‡ User āđāļ•āđˆāļĨāļ°āļ„āļ™ āļ—āļĩāđˆāļ–āļđāļāđ€āļāđ‡āļšāļ­āļĒāļđāđˆāđƒāļ™āļĢāļđāļ›āđāļšāļš JSON

āđ‚āļ”āļĒāļˆāļēāļāļ āļēāļžāļˆāļ°āđ€āļŦāđ‡āļ™āđ„āļ”āđ‰āļ§āđˆāļēāļŦāļ™āđ‰āļēāļ•āļēāļ‚āļ­āļ‡ JWT āļ„āļ·āļ­āļ‚āđ‰āļ­āļĄāļđāļĨāļ‚āļ­āļ‡ User āđāļ•āđˆāļĨāļ°āļ„āļ™āļ—āļĩāđˆāļ–āļđāļāđ€āļ‚āđ‰āļēāļĢāļŦāļąāļŠāđ€āļ›āđ‡āļ™ Token āļĄāļĩāļ—āļąāđ‰āļ‡āļŦāļĄāļ” 3 āļŠāđˆāļ§āļ™āļ”āđ‰āļ§āļĒāļāļąāļ™ āļ‹āļķāđˆāļ‡āđāļ•āđˆāļĨāļ°āļŠāđˆāļ§āļ™āļˆāļ°āļ–āļđāļāļ„āļąāđˆāļ™āļ”āđ‰āļ§āļĒāļŠāļąāļāļĨāļąāļāļĐāļ“āđŒāđ€āļ„āļĢāļ·āđˆāļ­āļ‡āļŦāļĄāļēāļĒāļˆāļļāļ” (.) āļ›āļĢāļ°āļāļ­āļšāđ„āļ›āļ”āđ‰āļ§āļĒ

  • Header (āļŠāļĩāđāļ”āļ‡) āđ€āļ›āđ‡āļ™āļ‚āđ‰āļ­āļĄāļđāļĨ Type āļ‚āļ­āļ‡ Token āđāļĨāļ°āļ‚āđ‰āļ­āļĄāļđāļĨ Algorithm āļ—āļĩāđˆāđƒāļŠāđ‰āđƒāļ™āļāļēāļĢāđ€āļ‚āđ‰āļēāļĢāļŦāļąāļŠ-āļ–āļ­āļ”āļĢāļŦāļąāļŠ āđ€āļāđ‡āļšāļ­āļĒāļđāđˆāđƒāļ™āļĢāļđāļ›āđāļšāļš JSON āļ”āļąāļ‡āļ•āļąāļ§āļ­āļĒāđˆāļēāļ‡
{
  "alg": "HS256",
  "typ": "JWT"
}

āļˆāļēāļāđƒāļ™āļ•āļąāļ§āļ­āļĒāđˆāļēāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨ JSON āļ‚āļ­āļ‡ Header āļˆāļ°āđ€āļŦāđ‡āļ™āļ§āđˆāļē Token āļ™āļĩāđ‰āđ€āļ›āđ‡āļ™āļ›āļĢāļ°āđ€āļ āļ— JWT āđāļĨāļ°āđƒāļŠāđ‰ Algorithm HS256 āđƒāļ™āļāļēāļĢāđ€āļ‚āđ‰āļēāļĢāļŦāļąāļŠ-āļ–āļ­āļ”āļĢāļŦāļąāļŠ

  • Payload (āļŠāļĩāļĄāđˆāļ§āļ‡) āđ€āļ›āđ‡āļ™āļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļĩāđˆāđƒāļŠāđ‰āđƒāļ™āļāļēāļĢāļĒāļ·āļ™āļĒāļąāļ™āļ•āļąāļ§āļ•āļ™āļ‚āļ­āļ‡ User āđāļĨāļ°āļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļĩāđˆāđ€āļ­āļēāđ„āļ§āđ‰āļāļģāļŦāļ™āļ”āļžāļĪāļ•āļīāļāļĢāļĢāļĄāļ‚āļ­āļ‡ Token āđ€āļāđ‡āļšāļ­āļĒāļđāđˆāđƒāļ™āļĢāļđāļ›āđāļšāļš JSON āļ”āļąāļ‡āļ•āļąāļ§āļ­āļĒāđˆāļēāļ‡
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

āļˆāļēāļāđƒāļ™āļ•āļąāļ§āļ­āļĒāđˆāļēāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨ JSON āļ‚āļ­āļ‡ Payload āļˆāļ°āđ€āļŦāđ‡āļ™āļ§āđˆāļē Token āļ™āļĩāđ‰āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨ Id āđāļĨāļ° Name āļ‚āļ­āļ‡ User āđ„āļ§āđ‰ āđāļĨāļ°āļĒāļąāļ‡āđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāđ€āļ§āļĨāļēāļŠāļĢāđ‰āļēāļ‡ Token āđ„āļ§āđ‰āļ”āđ‰āļ§āļĒ

  • Signature (āļŠāļĩāļŸāđ‰āļē) āđ€āļ›āđ‡āļ™āđ€āļŦāļĄāļ·āļ­āļ™ Digital Signed āļ—āļĩāđˆāļĄāļĩāđ„āļ§āđ‰āđ€āļŠāđ‡āļ„āļ„āļ§āļēāļĄāļ™āđˆāļēāđ€āļŠāļ·āđˆāļ­āļ–āļ·āļ­āļ‚āļ­āļ‡ Token āđ‚āļ”āļĒāđ€āļāļīāļ”āļˆāļēāļāļāļēāļĢāđ€āļ­āļē Payload āļ—āļĩāđˆāļ–āļđāļāđ€āļ‚āđ‰āļēāļĢāļŦāļąāļŠāļ”āđ‰āļ§āļĒ Algorithm āļ•āļēāļĄāļ—āļĩāđˆāļĢāļ°āļšāļļāđƒāļ™ Header āļĄāļēāļĢāļ§āļĄāđ€āļ‚āđ‰āļēāļāļąāļš Secret Key āļ—āļĩāđˆāđ€āļĢāļēāļ•āļąāđ‰āļ‡āļ‚āļķāđ‰āļ™āļĄāļē āļ”āļąāļ‡āļ•āļąāļ§āļ­āļĒāđˆāļēāļ‡
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  your-256-bit-secret
)

āļˆāļēāļāđƒāļ™āļ•āļąāļ§āļ­āļĒāđˆāļēāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļ‚āļ­āļ‡ Signature āļˆāļ°āđ€āļŦāđ‡āļ™āļ§āđˆāļē Secret Key āļ—āļĩāđˆ User āļ•āļąāđ‰āļ‡āļ‚āļķāđ‰āļ™āļ„āļ·āļ­ your-256-bit-secret āļ™āļąāđˆāļ™āđ€āļ­āļ‡

āđ‚āļ”āļĒāļ—āļļāļāļ„āļ™āļŠāļēāļĄāļēāļĢāļ–āļĨāļ­āļ‡āđ€āļ‚āđ‰āļēāđ„āļ›āđ€āļĨāđˆāļ™ āđ„āļ›āļĻāļķāļāļĐāļē āđāļĨāļ°āļ—āļģāļ„āļ§āļēāļĄāļĢāļđāđ‰āļˆāļąāļāļāļąāļš JWT (JSON Web Tokens)āđƒāļŦāđ‰āļ”āļĩāļĒāļīāđˆāļ‡āļ‚āļķāđ‰āļ™āļœāđˆāļēāļ™āđ€āļ§āđ‡āļ› https://jwt.io/ āļāļąāļ™āđ„āļ”āđ‰ āđ€āļĢāļīāđˆāļĄāļˆāļēāļāđ€āļĢāļēāļĨāļ­āļ‡āļ™āļģ Token āļ™āļĩāđ‰āđ„āļ›āļ§āļēāļ‡āđƒāļ™āļŠāđˆāļ­āļ‡āļ‚āļ­āļ‡ Encoded āđāļĨāđ‰āļ§āļĄāļēāļ”āļđāļœāļĨāļĨāļąāļžāļ˜āđŒāļ—āļēāļ‡āļ”āđ‰āļēāļ™āļ‚āļ§āļēāļāļąāļ™

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJjaGFyYWN0ZXIwMSIsIm5hbWUiOiJMdW5hIEZyZXlhIiwiaWF0IjoxNjk2OTA1MDI1fQ.82YKRXah5sINkAYFEBQB1Py9ttrUB7uC7DtVoXbfkik

āļˆāļēāļāđƒāļ™āļ•āļąāļ§āļ­āļĒāđˆāļēāļ‡ Token āđ€āļĄāļ·āđˆāļ­āđƒāļŠāđˆāļĨāļ‡āđ„āļ›āđƒāļ™āļŠāđˆāļ­āļ‡ Encoded āđāļĨāđ‰āļ§ āļœāļĨāļĨāļąāļžāļ˜āđŒāļ‚āļ­āļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļĩāđˆāļ–āļđāļāļ–āļ­āļ”āļĢāļŦāļąāļŠāļāđ‡āļˆāļ°āļ–āļđāļāđāļŠāļ”āļ‡āļ­āļĒāļđāđˆāđƒāļ™āļāļąāđˆāļ‡āļ‚āļ­āļ‡ Decoded āļ—āļąāđ‰āļ‡ 3 āļŠāđˆāļ§āļ™ āđāļ•āđˆāļˆāļēāļāļĢāļđāļ›āļ„āļļāļ“āļˆāļ°āđ€āļŦāđ‡āļ™āđāļˆāđ‰āļ‡āđ€āļ•āļ·āļ­āļ™ Error āļ—āļĩāđˆāļ‚āļķāđ‰āļ™āļ§āđˆāļē Invalid Signature āđāļĨāđ‰āļ§āļĄāļąāļ™āđ€āļāļīāļ”āļˆāļēāļāļ­āļ°āđ„āļĢāļāļąāļ™āļĨāđˆāļ° āļ–āđ‰āļēāļ—āļļāļāļ„āļ™āļĨāļ­āļ‡āđ„āļ›āļ”āļđāļ—āļĩāđˆāļŠāđˆāļ­āļ‡ VERIFY SIGNATURE (āļŠāļĩāļŸāđ‰āļē) āļāđ‡āļˆāļ°āđ€āļŦāđ‡āļ™āļ§āđˆāļēāļ‚āđ‰āļ­āļĄāļđāļĨ Secret Key āļ™āļąāđ‰āļ™āđ„āļĄāđˆāđ„āļ”āđ‰āļ–āļđāļāđ€āļ›āļĨāļĩāđˆāļĒāļ™āļ•āļēāļĄāļ‚āđ‰āļ­āļĄāļđāļĨāļ­āļ·āđˆāļ™ āđ† āđ„āļ›āļ”āđ‰āļ§āļĒ āļ—āļģāđƒāļŦāđ‰āđ€āļāļīāļ” Error āđ€āļ™āļ·āđˆāļ­āļ‡āļˆāļēāļāļ‚āđ‰āļ­āļĄāļđāļĨ Secret Key āđƒāļ™āļŠāđˆāļ­āļ‡ VERIFY SIGNATURE āļāļąāļšāļ‚āđ‰āļ­āļĄāļđāļĨ Secret Key āđƒāļ™āļĢāļŦāļąāļŠ āđ„āļĄāđˆāļ•āļĢāļ‡āļāļąāļ™āļ™āļąāđˆāļ™āđ€āļ­āļ‡

āļ—āļļāļāļ„āļ™āļ„āļ‡āļˆāļ°āđ€āļŦāđ‡āļ™āļāļąāļ™āđāļĨāđ‰āļ§āļ§āđˆāļē JWT āļ™āļĩāđˆāļŠāļēāļĄāļēāļĢāļ–āđ€āļ­āļēāļĢāļŦāļąāļŠāļĄāļēāļ–āļ­āļ”āļ„āļ§āļēāļĄāđ„āļ”āđ‰āļ‡āđˆāļēāļĒ āđ† āđ€āļĨāļĒ āđāļĨāđ‰āļ§āđāļšāļšāļ™āļĩāđ‰āđ€āļĢāļēāļ„āļ§āļĢāļˆāļ°āđƒāļŠāđˆāļ‚āđ‰āļ­āļĄāļđāļĨāļ­āļ°āđ„āļĢāļĨāļ‡āđ„āļ›āđƒāļ™ Payload āļāļąāļ™āļ”āļĩāļĨāđˆāļ° āļ„āļģāļ•āļ­āļšāļāđ‡āļ„āļ·āļ­ āđ€āļĢāļēāļ„āļ§āļĢāđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļĩāđˆāļ™āđ‰āļ­āļĒāļ—āļĩāđˆāļŠāļļāļ”āļ—āļĩāđˆāļŠāļēāļĄāļēāļĢāļ–āđƒāļŠāđ‰āļĢāļ°āļšāļļāļ•āļąāļ§āļ•āļ™āļ‚āļ­āļ‡āđ€āļĢāļēāđ„āļ”āđ‰ āđ‚āļ”āļĒāđ„āļĄāđˆāļ„āļ§āļĢāđ€āļāđ‡āļšāļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļĩāđˆāđ€āļ›āđ‡āļ™āļ„āļ§āļēāļĄāļĨāļąāļš āļŦāļĢāļ·āļ­ Password āđ‚āļ”āļĒāļ•āļĢāļ‡

āļ§āļīāļ˜āļĩāđƒāļŠāđ‰āļ‡āļēāļ™ JWT (JSON Web Tokens) āđƒāļ™āļāļēāļĢ Authentication

āļ‹āļķāđˆāļ‡āđƒāļ™āļ‚āļąāđ‰āļ™āļ•āļ­āļ™āļ•āđˆāļ­āđ„āļ›āđ€āļĢāļēāļˆāļ°āļĄāļēāļĨāļ­āļ‡āđ€āļ‚āļĩāļĒāļ™ Code āļ—āļģāļĢāļ°āļšāļš Authentication āļ‚āļ­āļ‡ āļĢāļ°āļšāļšāļˆāļąāļ”āļāļēāļĢāļŠāļīāļ™āļ„āđ‰āļē āļ”āđ‰āļ§āļĒ Passport.js āđāļĨāļ° JWT āļ­āļĒāđˆāļēāļ‡āļ‡āđˆāļēāļĒāļāļąāļ™

  • āļāđˆāļ­āļ™āđ€āļĢāļīāđˆāļĄāđƒāļŦāđ‰āļ—āļļāļāļ„āļ™āļŠāļĢāđ‰āļēāļ‡ Web Application āļĢāļ°āļšāļšāļˆāļąāļ”āļāļēāļĢāļŠāļīāļ™āļ„āđ‰āļē āļ”āđ‰āļ§āļĒ Node.js āđāļĨāļ° Express āļ­āļĒāđˆāļēāļ‡āļ‡āđˆāļēāļĒāļ‚āļķāđ‰āļ™āļĄāļēāļāļąāļ™āļāđˆāļ­āļ™ āļ”āļđāļĢāļđāļ›āđāļšāļšāļ„āļĢāđˆāļēāļ§ āđ† āđ„āļ”āđ‰āļˆāļēāļ Code āđƒāļ™āđ„āļŸāļĨāđŒ index.js āļ‚āđ‰āļēāļ‡āļĨāđˆāļēāļ‡āļ™āļĩāđ‰āđ€āļĨāļĒ
const express = require("express");

const app = express();
const port = 5000;

let products = [
  { id: 1, name: "Laptop", category: "Electronics", price: 1000, stock: 5 },
  { id: 2, name: "Phone", category: "Electronics", price: 500, stock: 10 },
];

app.get("/products", (req, res) => {
  res.status(200).json(products);
});

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});

āļ–āđ‰āļēāļ—āļļāļāļ„āļ™āļŠāļĢāđ‰āļēāļ‡ Web Application āļĢāļ°āļšāļšāļˆāļąāļ”āļāļēāļĢāļŠāļīāļ™āļ„āđ‰āļē āđ€āļŠāļĢāđ‡āļˆāđāļĨāđ‰āļ§āļ‡āļąāđ‰āļ™āđ€āļĢāļēāļāđ‡āđ„āļ›āđ€āļĢāļīāđˆāļĄāļ—āļģāļĢāļ°āļšāļš Authentication āļāļąāļ™āđ„āļ”āđ‰āđ€āļĨāļĒ

  • āđ€āļĢāļīāđˆāļĄāļˆāļēāļāļāļēāļĢāļ•āļīāļ”āļ•āļąāđ‰āļ‡ Dependencies āļ—āļĩāđˆāļˆāļģāđ€āļ›āđ‡āļ™āļ•āđ‰āļ­āļ‡āđƒāļŠāđ‰ āļ”āđ‰āļ§āļĒāļ„āļģāļŠāļąāđˆāļ‡
npm install body-parser jwt-simple passport passport-jwt –save
  • āļ•āđˆāļ­āļĄāļēāļ—āļģāļĢāļ°āļšāļš Login āļœāđˆāļēāļ™ API āļ—āļĩāđˆāļˆāļ°āļŠāļĢāđ‰āļēāļ‡ JWT āđƒāļŦāđ‰ User āđƒāļŠāđ‰āļ—āļģāļāļīāļˆāļāļĢāļĢāļĄāļ•āđˆāļ­āđ„āļ›āđƒāļ™āļĢāļ°āļšāļš āđ‚āļ”āļĒāđ€āļžāļīāđˆāļĄ Code āļ™āļĩāđ‰āļĨāļ‡āđ„āļ›āđƒāļ™āđ„āļŸāļĨāđŒ index.js
const bodyParser = require("body-parser");

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

const loginUsename = (req, res, next) => {
  if (req.body.username === "admin" && req.body.password === "1234") {
    next();
  } else {
    res.send("Error: username or password is incorrect");
  }
};

app.post("/login", loginUsename, (req, res) => {
  res.send("User " + req.body.username + " login success");
});
  • āļˆāļēāļāļ™āļąāđ‰āļ™āđƒāļŦāđ‰āđ€āļĢāļēāļĨāļ­āļ‡āđ€āļĢāļĩāļĒāļāđƒāļŠāđ‰ API āļ™āļĩāđ‰āļœāđˆāļēāļ™ Postman āđ€āļžāļ·āđˆāļ­ Test āļĢāļ°āļšāļš Login āđ€āļĄāļ·āđˆāļ­ User āļāļĢāļ­āļ username āļŦāļĢāļ·āļ­ password āđ„āļĄāđˆāļ–āļđāļāļ•āđ‰āļ­āļ‡

āđ€āļĄāļ·āđˆāļ­ User āļāļĢāļ­āļ username āđāļĨāļ° password āļ–āļđāļāļ•āđ‰āļ­āļ‡

  • āļ•āđˆāļ­āđ„āļ›āđ€āļĢāļēāļˆāļ°āđāļāđ‰āđ„āļ‚ Code āđƒāļ™āļ„āļģāļŠāļąāđˆāļ‡ app.post(“/login”) āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰āļĢāļ°āļšāļš Login āļ‚āļ­āļ‡āđ€āļĢāļēāļŠāđˆāļ‡ JWT āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡āđ€āļŠāļĢāđ‡āļˆāđāļĨāđ‰āļ§āļāļĨāļąāļšāđ„āļ›āļĒāļąāļ‡ User āđ‚āļ”āļĒāđƒāļ™āļŠāđˆāļ§āļ™āļ‚āļ­āļ‡āļ‚āđ‰āļ­āļĄāļđāļĨ Payload āđ€āļĢāļēāļˆāļ°āđƒāļŠāđˆāđ€āļ›āđ‡āļ™
payload = { sub: āļ‚āđ‰āļ­āļĄāļđāļĨ username, iat: āļ‚āđ‰āļ­āļĄāļđāļĨāđ€āļ§āļĨāļēāļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡ Token āļ™āļĩāđ‰ }

āļˆāļ°āđ„āļ”āđ‰āđ€āļ›āđ‡āļ™ Code āļ—āļĩāđˆāļ›āļĢāļąāļšāđāļāđ‰āđāļĨāđ‰āļ§āđƒāļ™āđ„āļŸāļĨāđŒ index.js āļ”āļąāļ‡āļ™āļĩāđ‰

const jwt = require("jwt-simple");
const SECRET = "USER_SECRET_KEY";

app.post("/login", loginUsename, (req, res) => {
  const payload = {
    sub: req.body.username,
    iat: new Date().getTime(),
  };
  res.send(jwt.encode(payload, SECRET));
});
  • āļ—āļģāđƒāļŦāđ‰āđ€āļĄāļ·āđˆāļ­āđ€āļĢāļēāđ€āļĢāļĩāļĒāļāđƒāļŠāđ‰ API āļ™āļĩāđ‰āļœāđˆāļēāļ™ Postman āļ­āļĩāļāļ„āļĢāļąāđ‰āļ‡ āļĢāļ°āļšāļšāļāđ‡āļˆāļ°āļŠāđˆāļ‡ JWT āļāļĨāļąāļšāļĄāļēāđƒāļŦāđ‰āđ€āļĢāļē
  • āļ‹āļķāđˆāļ‡āđƒāļ™āļāļēāļĢāļĒāļ·āļ™āļĒāļąāļ™āļ•āļąāļ§āļ•āļ™āļ™āļąāđ‰āļ™ āđ€āļĢāļēāļˆāļ°āđƒāļŠāđ‰ Passport.js āđ€āļ‚āđ‰āļēāļĄāļēāđ€āļ›āđ‡āļ™āļ•āļąāļ§āļāļĨāļēāļ‡ āđ‚āļ”āļĒāđ€āļĢāļīāđˆāļĄāļˆāļēāļāļāļēāļĢāļŠāļĢāđ‰āļēāļ‡āļāļĢāļ°āļšāļ§āļ™āļāļēāļĢāļĒāļ·āļ™āļĒāļąāļ™āļ•āļąāļ§āļ•āļ™āļ”āđ‰āļ§āļĒ JWT āļœāđˆāļēāļ™ Code āđ€āļŦāļĨāđˆāļēāļ™āļĩāđ‰
const ExtractJwt = require("passport-jwt").ExtractJwt;
const JwtStrategy = require("passport-jwt").Strategy;

const jwtOptions = {
  jwtFromRequest: ExtractJwt.fromHeader("authorization"),
  secretOrKey: SECRET,
};
const jwtAuth = new JwtStrategy(jwtOptions, (payload, done) => {
  if (payload.sub === "admin") done(null, true);
  else done(null, false);
});
  • āļˆāļēāļāļ™āļąāđ‰āļ™āļ™āļģāđ€āļ­āļēāļāļĢāļ°āļšāļ§āļ™āļāļēāļĢāļĒāļ·āļ™āļĒāļąāļ™āļ•āļąāļ§āļ•āļ™āļ”āđ‰āļ§āļĒ JWT āļ—āļĩāđˆāļŠāļĢāđ‰āļēāļ‡āđ„āļ§āđ‰āđ„āļ›āđ€āļŠāļ·āđˆāļ­āļĄāļāļąāļš Passport
const passport = require("passport");

passport.use(jwtAuth);
  • āļŠāļļāļ”āļ—āđ‰āļēāļĒāđ€āļĢāļĩāļĒāļāđƒāļŠāđ‰ Passport āđƒāļ™āļĢāļđāļ›āđāļšāļš Middleware āļœāđˆāļēāļ™āļ„āļģāļŠāļąāđˆāļ‡ app.get(“/products”) āļ—āļĩāđˆāļˆāļ°āđāļŠāļ”āļ‡āļŠāļīāļ™āļ„āđ‰āļēāļ—āļąāđ‰āļ‡āļŦāļĄāļ”āļ—āļĩāđˆāļĄāļĩāļ­āļĒāļđāđˆāđƒāļ™āļĢāļ°āļšāļšāļˆāļąāļ”āļāļēāļĢāļŠāļīāļ™āļ„āđ‰āļē
const requireJWTAuth = passport.authenticate("jwt", { session: false });

app.get("/products", requireJWTAuth, (req, res) => {
  res.status(200).json(products);
});
  • āđ€āļžāļĩāļĒāļ‡āđāļ„āđˆāļ™āļĩāđ‰ āļĢāļ°āļšāļš Authentication āļ‚āļ­āļ‡ āļĢāļ°āļšāļšāļˆāļąāļ”āļāļēāļĢāļŠāļīāļ™āļ„āđ‰āļē āļāđ‡āđ€āļ›āđ‡āļ™āļ­āļąāļ™āđ€āļŠāļĢāđ‡āļˆāđ€āļĢāļĩāļĒāļšāļĢāđ‰āļ­āļĒ āđ‚āļ”āļĒāļ—āļļāļāļ„āļ™āļŠāļēāļĄāļēāļĢāļ–āļĨāļ­āļ‡ Test āđ„āļ”āđ‰ āļœāđˆāļēāļ™ Postman āđ„āļ”āđ‰āđ€āļ›āđ‡āļ™āļœāļĨāļĨāļąāļžāļ˜āđŒāļ”āļąāļ‡āļ™āļĩāđ‰

āđ€āļĄāļ·āđˆāļ­ user āļŠāđˆāļ‡āļ„āļģāļĢāđ‰āļ­āļ‡āļ‚āļ­ GET āļ‚āđ‰āļ­āļĄāļđāļĨāļˆāļēāļāļĢāļ°āļšāļšāđ‚āļ”āļĒāđ„āļĄāđˆāđ„āļ”āđ‰āđāļ™āļš token āđ„āļ›āļ”āđ‰āļ§āļĒ āļĢāļ°āļšāļšāļˆāļķāļ‡āļŠāđˆāļ‡ Unauthorized āļāļĨāļąāļšāļĄāļē

āđ€āļĄāļ·āđˆāļ­ user āļŠāđˆāļ‡āļ„āļģāļĢāđ‰āļ­āļ‡āļ‚āļ­ GET āļ‚āđ‰āļ­āļĄāļđāļĨāļˆāļēāļāļĢāļ°āļšāļšāđ‚āļ”āļĒāđāļ™āļš token āđ„āļ›āļ”āđ‰āļ§āļĒ āļĢāļ°āļšāļšāļˆāļķāļ‡āļŠāđˆāļ‡ āļ‚āđ‰āļ­āļĄāļđāļĨāļŠāļīāļ™āļ„āđ‰āļēāļ—āļąāđ‰āļ‡āļŦāļĄāļ”āđƒāļ™āļĢāļ°āļšāļš āļāļĨāļąāļšāļĄāļē

  • āļ—āļļāļāļ„āļ™āļŠāļēāļĄāļēāļĢāļ–āļ”āļđāļŠāļĢāļļāļ› Code āļ—āļąāđ‰āļ‡āļŦāļĄāļ”āđƒāļ™āļāļēāļĢāļ—āļģāļĢāļ°āļšāļš Authentication āļ‚āļ­āļ‡ āļĢāļ°āļšāļšāļˆāļąāļ”āļāļēāļĢāļŠāļīāļ™āļ„āđ‰āļē āļ­āļĒāđˆāļēāļ‡āļ‡āđˆāļēāļĒ āđ„āļ”āđ‰āļ—āļĩāđˆāļ‚āđ‰āļēāļ‡āļĨāđˆāļēāļ‡āļ™āļĩāđ‰āđ€āļĨāļĒ
const express = require("express");
const bodyParser = require("body-parser");
const jwt = require("jwt-simple");
const passport = require("passport");

const app = express();
const port = 5000;
const ExtractJwt = require("passport-jwt").ExtractJwt;
const JwtStrategy = require("passport-jwt").Strategy;
const SECRET = "USER_SECRET_KEY";

const jwtOptions = {
  jwtFromRequest: ExtractJwt.fromHeader("authorization"),
  secretOrKey: SECRET,
};
const jwtAuth = new JwtStrategy(jwtOptions, (payload, done) => {
  if (payload.sub === "admin") done(null, true);
  else done(null, false);
});

passport.use(jwtAuth);

const requireJWTAuth = passport.authenticate("jwt", { session: false });

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

const loginUsename = (req, res, next) => {
  if (req.body.username === "admin" && req.body.password === "1234") {
    next();
  } else {
    res.send("Error: username or password is incorrect");
  }
};

let products = [
  { id: 1, name: "Laptop", category: "Electronics", price: 1000, stock: 5 },
  { id: 2, name: "Phone", category: "Electronics", price: 500, stock: 10 },
];

app.post("/login", loginUsename, (req, res) => {
  const payload = {
    sub: req.body.username,
    iat: new Date().getTime(),
  };
  res.send(jwt.encode(payload, SECRET));
});

app.get("/products", requireJWTAuth, (req, res) => {
  res.status(200).json(products);
});

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});

āļŠāļĢāļļāļ›

āļˆāļēāļāļ—āļĩāđˆāđ„āļ”āđ‰āļāļĨāđˆāļēāļ§āļĄāļēāđƒāļ™āļ‚āđ‰āļēāļ‡āļ•āđ‰āļ™āļ—āļļāļāļ„āļ™āļ„āļ‡āļˆāļ°āđ„āļ”āđ‰āļĢāļđāđ‰āļāļąāļ™āđāļĨāđ‰āļ§āļ§āđˆāļē āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™ JWT (JSON Web Tokens) āđƒāļ™āļāļēāļĢāļ—āļģāļĢāļ°āļšāļš Authentication āļ™āļąāđ‰āļ™āđ„āļĄāđˆāđƒāļŠāđˆāđ€āļĢāļ·āđˆāļ­āļ‡āļĒāļēāļāđ€āļĨāļĒ āļ­āļĩāļāļ—āļąāđ‰āļ‡āļĒāļąāļ‡āļˆāļ°āļŠāđˆāļ§āļĒāđ€āļžāļīāđˆāļĄāļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒāđƒāļŦāđ‰āļāļąāļšāļĢāļ°āļšāļšāļ‚āļ­āļ‡āđ€āļĢāļēāđƒāļ™āļāļēāļĢāļ•āļĢāļ§āļˆāļŠāļ­āļšāļŠāļīāļ—āļ˜āļīāđŒāļāļēāļĢāđ€āļ‚āđ‰āļēāļ–āļķāļ‡āļ‚āđ‰āļ­āļĄāļđāļĨāļ‚āļ­āļ‡ User āđāļ•āđˆāļĨāļ°āļ„āļ™ āļœāđˆāļēāļ™āļāļēāļĢāđ€āļ‚āđ‰āļēāļĢāļŦāļąāļŠāļˆāļēāļāļ‚āđ‰āļ­āļĄāļđāļĨāļ—āļĩāđˆāđƒāļŠāđ‰āļĒāļ·āļ™āļĒāļąāļ™āļ•āļąāļ§āļ•āļ™āđƒāļ™āļĢāļđāļ›āđāļšāļš JSON āļ—āļĩāđˆāđ€āļŠāļ·āđˆāļ­āļ–āļ·āļ­āđ„āļ”āđ‰ āđāļĨāļ°āļĄāļĩāļ„āļ§āļēāļĄāļ›āļĨāļ­āļ”āļ āļąāļĒāđƒāļ™āļĢāļ°āļ”āļąāļšāļ™āļķāļ‡āļ­āļĩāļāļ”āđ‰āļ§āļĒ


āļ‚āđ‰āļ­āļĄāļđāļĨāļ­āđ‰āļēāļ‡āļ­āļīāļ‡

  1. Introduction to JSON Web Tokens āļŠāļ·āļšāļ„āđ‰āļ™āđ€āļĄāļ·āđˆāļ­ 9 āļ•āļļāļĨāļēāļ„āļĄ 2566 āļˆāļēāļ: https://jwt.io/introduction
  2. JSON Web Token āļĄāļēāļ•āļĢāļāļēāļ™āđƒāļŦāļĄāđˆ āđƒāļ™āļāļēāļĢāļ—āļģ Authentication āļŠāļ·āļšāļ„āđ‰āļ™āđ€āļĄāļ·āđˆāļ­ 9 āļ•āļļāļĨāļēāļ„āļĄ 2566 āļˆāļēāļ: https://medium.com/rootusercc/json-web-token-āļĄāļēāļ•āļĢāļāļēāļ™āđƒāļŦāļĄāđˆ-āđƒāļ™āļāļēāļĢāļ—āļģ-authentication-b0760dd9acd1
  3. āļ—āļģ Stateless Authentication āļšāļ™ Express āļ”āđ‰āļ§āļĒ Passport.js + JWT āļŠāļ·āļšāļ„āđ‰āļ™āđ€āļĄāļ·āđˆāļ­ 9 āļ•āļļāļĨāļēāļ„āļĄ 2566 āļˆāļēāļ: https://medium.com/@kennwuttisasiwat/āļ—āļģ-authentication-āļšāļ™-express-āļ”āđ‰āļ§āļĒ-passport-js-jwt-34fb1169a410
  4. āļ—āļģāļ„āļ§āļēāļĄāļĢāļđāđ‰āļˆāļąāļāļāļąāļš JWT (Json Web Token) āļŠāļ·āļšāļ„āđ‰āļ™āđ€āļĄāļ·āđˆāļ­ 9 āļ•āļļāļĨāļēāļ„āļĄ 2566 āļˆāļēāļ: https://www.jittagornp.me/blog/what-is-jwt/

āđ€āļĢāļēāđƒāļŠāđ‰āļ„āļļāļāļāļĩāđ‰āđ€āļžāļ·āđˆāļ­āļžāļąāļ’āļ™āļēāļ›āļĢāļ°āļŠāļīāļ—āļ˜āļīāļ āļēāļž āđāļĨāļ°āļ›āļĢāļ°āļŠāļšāļāļēāļĢāļ“āđŒāļ—āļĩāđˆāļ”āļĩāđƒāļ™āļāļēāļĢāđƒāļŠāđ‰āđ€āļ§āđ‡āļšāđ„āļ‹āļ•āđŒāļ‚āļ­āļ‡āļ„āļļāļ“ āļ„āļļāļ“āļŠāļēāļĄāļēāļĢāļ–āļĻāļķāļāļĐāļēāļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”āđ„āļ”āđ‰āļ—āļĩāđˆ āļ™āđ‚āļĒāļšāļēāļĒāļ„āļ§āļēāļĄāđ€āļ›āđ‡āļ™āļŠāđˆāļ§āļ™āļ•āļąāļ§ āđāļĨāļ°āļŠāļēāļĄāļēāļĢāļ–āļˆāļąāļ”āļāļēāļĢāļ„āļ§āļēāļĄāđ€āļ›āđ‡āļ™āļŠāđˆāļ§āļ™āļ•āļąāļ§āđ€āļ­āļ‡āđ„āļ”āđ‰āļ‚āļ­āļ‡āļ„āļļāļ“āđ„āļ”āđ‰āđ€āļ­āļ‡āđ‚āļ”āļĒāļ„āļĨāļīāļāļ—āļĩāđˆ āļ•āļąāđ‰āļ‡āļ„āđˆāļē

āļ•āļąāđ‰āļ‡āļ„āđˆāļēāļ„āļ§āļēāļĄāđ€āļ›āđ‡āļ™āļŠāđˆāļ§āļ™āļ•āļąāļ§

āļ„āļļāļ“āļŠāļēāļĄāļēāļĢāļ–āđ€āļĨāļ·āļ­āļāļāļēāļĢāļ•āļąāđ‰āļ‡āļ„āđˆāļēāļ„āļļāļāļāļĩāđ‰āđ‚āļ”āļĒāđ€āļ›āļīāļ”/āļ›āļīāļ” āļ„āļļāļāļāļĩāđ‰āđƒāļ™āđāļ•āđˆāļĨāļ°āļ›āļĢāļ°āđ€āļ āļ—āđ„āļ”āđ‰āļ•āļēāļĄāļ„āļ§āļēāļĄāļ•āđ‰āļ­āļ‡āļāļēāļĢ āļĒāļāđ€āļ§āđ‰āļ™ āļ„āļļāļāļāļĩāđ‰āļ—āļĩāđˆāļˆāļģāđ€āļ›āđ‡āļ™

āļĒāļ­āļĄāļĢāļąāļšāļ—āļąāđ‰āļ‡āļŦāļĄāļ”
āļˆāļąāļ”āļāļēāļĢāļ„āļ§āļēāļĄāđ€āļ›āđ‡āļ™āļŠāđˆāļ§āļ™āļ•āļąāļ§
  • āļ„āļļāļāļāļĩāđ‰āļ—āļĩāđˆāļˆāļģāđ€āļ›āđ‡āļ™
    āđ€āļ›āļīāļ”āđƒāļŠāđ‰āļ‡āļēāļ™āļ•āļĨāļ­āļ”

    āļ›āļĢāļ°āđ€āļ āļ—āļ‚āļ­āļ‡āļ„āļļāļāļāļĩāđ‰āļĄāļĩāļ„āļ§āļēāļĄāļˆāļģāđ€āļ›āđ‡āļ™āļŠāļģāļŦāļĢāļąāļšāļāļēāļĢāļ—āļģāļ‡āļēāļ™āļ‚āļ­āļ‡āđ€āļ§āđ‡āļšāđ„āļ‹āļ•āđŒ āđ€āļžāļ·āđˆāļ­āđƒāļŦāđ‰āļ„āļļāļ“āļŠāļēāļĄāļēāļĢāļ–āđƒāļŠāđ‰āđ„āļ”āđ‰āļ­āļĒāđˆāļēāļ‡āđ€āļ›āđ‡āļ™āļ›āļāļ•āļī āđāļĨāļ°āđ€āļ‚āđ‰āļēāļŠāļĄāđ€āļ§āđ‡āļšāđ„āļ‹āļ•āđŒ āļ„āļļāļ“āđ„āļĄāđˆāļŠāļēāļĄāļēāļĢāļ–āļ›āļīāļ”āļāļēāļĢāļ—āļģāļ‡āļēāļ™āļ‚āļ­āļ‡āļ„āļļāļāļāļĩāđ‰āļ™āļĩāđ‰āđƒāļ™āļĢāļ°āļšāļšāđ€āļ§āđ‡āļšāđ„āļ‹āļ•āđŒāļ‚āļ­āļ‡āđ€āļĢāļēāđ„āļ”āđ‰
    āļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”āļ„āļļāļāļāļĩāđ‰

  • āļ„āļļāļāļāļĩāđ‰āļŠāļģāļŦāļĢāļąāļšāļāļēāļĢāļ•āļīāļ”āļ•āļēāļĄāļ—āļēāļ‡āļāļēāļĢāļ•āļĨāļēāļ”

    āļ›āļĢāļ°āđ€āļ āļ—āļ‚āļ­āļ‡āļ„āļļāļāļāļĩāđ‰āļ—āļĩāđˆāļĄāļĩāļ„āļ§āļēāļĄāļˆāļģāđ€āļ›āđ‡āļ™āđƒāļ™āļāļēāļĢāđƒāļŠāđ‰āļ‡āļēāļ™āđ€āļžāļ·āđˆāļ­āļāļēāļĢāļ§āļīāđ€āļ„āļĢāļēāļ°āļŦāđŒ āđāļĨāļ° āļ™āļģāđ€āļŠāļ™āļ­āđ‚āļ›āļĢāđ‚āļĄāļŠāļąāļ™ āļŠāļīāļ™āļ„āđ‰āļē āļĢāļ§āļĄāļ–āļķāļ‡āļŦāļĨāļąāļāļŠāļđāļ•āļĢāļŸāļĢāļĩ āđāļĨāļ° āļŠāļīāļ—āļ˜āļīāļžāļīāđ€āļĻāļĐāļ•āđˆāļēāļ‡ āđ† āļ„āļļāļ“āļŠāļēāļĄāļēāļĢāļ–āđ€āļĨāļ·āļ­āļāļ›āļīāļ”āļ„āļļāļāļāļĩāđ‰āļ›āļĢāļ°āđ€āļ āļ—āļ™āļĩāđ‰āđ„āļ”āđ‰āđ‚āļ”āļĒāđ„āļĄāđˆāļŠāđˆāļ‡āļœāļĨāļ•āđˆāļ­āļāļēāļĢāļ—āļģāļ‡āļēāļ™āļŦāļĨāļąāļ āđ€āļ§āđ‰āļ™āđāļ•āđˆāļāļēāļĢāļ™āļģāđ€āļŠāļ™āļ­āđ‚āļ›āļĢāđ‚āļĄāļŠāļąāļ™āļ—āļĩāđˆāļ­āļēāļˆāđ„āļĄāđˆāļ•āļĢāļ‡āļāļąāļšāļ„āļ§āļēāļĄāļ•āđ‰āļ­āļ‡āļāļēāļĢ
    āļĢāļēāļĒāļĨāļ°āđ€āļ­āļĩāļĒāļ”āļ„āļļāļāļāļĩāđ‰

āļšāļąāļ™āļ—āļķāļāļāļēāļĢāļ•āļąāđ‰āļ‡āļ„āđˆāļē