JWT یا JSON Web Tokens یک استاندارد باز است که در RFC 7519 منتشر شد. JWT در عمل روشی برای بررسی ادعاهای وارده درباره یک منبع خاص با استفاده از اشیاء JSON است. محتوای داخل این توکن ها قابل اعتماد هستند چرا که به صورت دیجیتالی امضا شده اند. این امضای دیجیتالی می تواند با کلیدهای متقارن (مانند الگوریتم های HMAC) یا کلیدهای نامتقارن (مانند الگوریتم های RSA یا ECDSA) انجام شود. همچنین در نظر داشته باشید که JWT توانایی انتقال داده های رمزنگاری شده را نیز دارد.
باید در نظر داشت که توکن JWT در حالت عادی رمزنگاری نشده است و رشته ای که مشاهده می کنیم تنها یک رشته base64 می باشد بنابراین می تواند به سادگی decode شود. با این حساب پاسخ به سوال «آیا JWT امن است؟» بستگی به نحوه پیاده سازی آن دارد.
هر توکن JWT یه بخش دارد:
همانطور که گفتم هر توکن JWT یک رشته Base64 است بنابراین هر کدام از این قسمت ها با استفاده از علامت نقطه از هم جدا می شوند. با این حساب هر توکن JWT ساختار زیر را خواهد داشت:
[header].[payload].[signature]
من یک مثال ساده از این توکن ها را برایتان قرار می دهم:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.POstGetfAytaZS82wHcjoTyoqhMyxXiWdR7Nn7A29DNSl0EiXLdwJ6xC6AfgZWF1bOsS_TuYI3OG85AmiExREkrS6tDfTQ2B3WXlrr-wp5AokiRbz3_oB4OxG-W9KcEEbDRcZc0nH3L7LzYptiy1PtAylQGxHTWZXtGz4ht0bAecBgmpdgXMguEIcoqPJ1n3pIWk_dUZegpqx0Lka21H6XxUTxiy8OcaarA8zdnPUnV6AmNP3ecFawIFYdvJB_cm-GvpCSbr8G8y_Mllj8f4x9nBH8pQux89_6gUY618iYv7tuPWBFfEbLxtF2pZS6YC1aSfLQxeNe8djT9YjpvRZA
در صورتی که قسمت header از توکن بالا را برداشته و decode کنیم، داده زیر را دریافت می کنیم:
{ "alg":"RS256", "typ":"JWT" }
تمام قسمت های دیگر این توکن نیز به همین شکل decode می شوند.
ما در این قسمت سه نوع مهم توکن های JWT را بررسی می کنیم:
برای ساخت هر توکن JWT نکاتی امنیتی وجود دارد که باید همیشه رعایت کنید. ما در این قسمت به بررسی برخی از این نکات می پردازیم.
به غیر از مواردی خاص، توکن های JWT همیشه باید امضا شوند. زمانی که ما یک توکن را امضا می کنیم، مطمئن می شویم که محتوای آن به هیچ عنوان تغییری نکرده است. چطور؟ ما ابتدا توکن را با کلید خاصی می سازیم و سپس زمانی که کاربری این توکن را برای ما ارسال کند، کلید آن را بررسی می کنیم. در صورتی که امضای تولید شده توسط ما با امضای توکن یکی نباشد یعنی محتوای آن تغییر پیدا کرده است و آن را رد می کنیم.
حالا که می دانیم باید توکن ها را امضا کنیم سوالی پیش می آید: با چه الگوریتمی این کار را انجام بدهیم؟ الگوریتمی که برای امضا کردن توکن ها استفاده می کنید باید یک الگوریتم قوی باشد. در وهله اول باید بدانید که الگوریتم های متقارن مانند HMAC در برابر حملات brute-force ضعیف هستند مگر آنکه کلید بسیار قوی باشد بنابراین اگر می خواهید از الگوریتم های متقارن استفاده کنید باید entropy کافی برای آن داشته باشید. من شخصا استفاده از الگوریتم های نامتقارن مانند RSA را پیشنهاد می کنم.
توکن های JWT پس از امضا شدن تا ابد معتبر هستند مگر آنکه تاریخ انقضایی برایشان تعریف کرده باشید. چرا؟ به دلیل اینکه پس از گذشت زمان خاصی بهتر است کاربر دوباره مجبور به login و دریافت توکن جدید شود تا شانس نشت توکن یا سوء استفاده دیگران از آن کاهش یابد. البته همیشه بهتر است که یک id خاص را برای هر توکن در نظر بگیرید تا بعدا به کاربر اجازه منقضی کردن توکن به صورت دستی را بدهید.
برای مدیریت بهتر و ساده تر توکن ها بهتر است همیشه خصوصیات issuer (صادرکننده) و audience (مخاطب یا دریافت کننده) را در توکن های خود تعریف کنید. با انجام این کار دریافت کننده توکن به راحتی می تواند متوجه شود که این توکن برای او صادر شده است یا خیر. همچنین زمانی که توکن JWT دریافت می کنید باید این دو خصوصیت در آن را اعتبارسنجی کنید تا هکری با استفاده از توکن سایت دیگری به منابع ما دسترسی پیدا نکند.
از آنجایی که توکن های JWT تنها رشته های Base64 هستند، نباید داده های حساس خود را درون این توکن ها قرار بدهید. در صورتی که باید چنین کاری را انجام بدهید، حتما payload را رمزنگاری (encrypt) کنید.
امضا کردن توکن ها تنها راهی است که برای تشخیص تمامیت و صحت توکن ها داریم. هکر ها می توانند توکن را قبل از رسیدن به سرور ما دریافت کرده، امضای دیجیتالی را حذف کرده و نهایتا درخواست را ویرایش کنند بنابراین هیچ گاه توکن های امضا نشده یا توکن هایی با ‘alg: “none را قبول نکنید.
منبع: وبسایت bbva
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.