کتابخانه pyjwt در پایتون
PyJWT یک کتابخانهٔ محبوب در پایتون برای تولید، رمزگشایی و اعتبارسنجی JSON Web Token (JWT) است. JWT یک استاندارد باز (RFC 7519) برای انتقال امن ادعاها (claims) بین دو طرف بهصورت JSON است. این مقاله بهطور جامع کار با کتابخانه pyjwt، نکات امنیتی، مثالهای واقعی و بهترین شیوهها را توضیح میدهد.
چرا از JWT و PyJWT استفاده کنیم؟
- سبک و مستقل از پروتکل: قابل استفاده در RESTful APIها و احراز هویت بین سرویسها.
- قابل امضا و رمزنگاری: میتوان ادعاها را امضا کرد تا یکپارچگی تضمین شود (HMAC یا RSA/EC).
- پشتیبانی ساده در پایتون: PyJWT رابطی ساده برای encode/decode فراهم میکند.
نصب و نسخهگذاری
نصب بهسادگی با pip انجام میشود:
pip install PyJWTتوجه کنید نام پکیج در pip با حروف بزرگ/کوچک حساس نیست اما در import باید از import jwt استفاده کنید.
موارد استفادهٔ متداول
- احراز هویت کاربران در APIها (Bearer token در هدر Authorization)
- امانتداری بین سرویسها (service-to-service authentication)
- انتقال امن اطلاعات موقتی مانند اطلاعات سبد خرید یا لینکهای تاییدی
مثال ساده: تولید و خواندن JWT با HS256
import jwt
import datetime
secret = "your-very-secret-key"
payload = {
"sub": "user123",
"role": "admin",
"exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=30)
}
token = jwt.encode(payload, secret, algorithm="HS256")
print(token)
# decode
decoded = jwt.decode(token, secret, algorithms=["HS256"])
print(decoded)در این مثال payload شامل کلیدهای استاندارد مانند sub (subject) و exp (expiration) است. متد jwt.encode توکن امضا شده تولید میکند و jwt.decode آن را بررسی و دیکد میکند. همیشه پارامتر algorithms را در decode مشخص کنید تا از حملات احتمالی جلوگیری شود.
استفاده با کلیدهای RSA (RS256)
# فرض کنید private_key و public_key بهصورت PEM در دسترس هستند
token = jwt.encode(payload, private_key, algorithm="RS256")
# اعتبارسنجی با کلید عمومی
decoded = jwt.decode(token, public_key, algorithms=["RS256"])RS256 از امضای نامتقارن استفاده میکند: سرویس صادرکننده با کلید خصوصی امضا میکند و سرویسهای مصرفکننده با کلید عمومی اعتبارسنجی میکنند. این الگو هنگام توزیع توکن بین سرویسها بسیار امنتر است زیرا کلید خصوصی نیازی به اشتراکگذاری ندارد.
خطاها و مدیریت استثناها
PyJWT چندین استثنای مهم دارد که باید در کد مدیریت شوند:
- ExpiredSignatureError: توکن منقضی شده است.
- InvalidSignatureError: امضای توکن معتبر نیست.
- DecodeError: ساختار توکن نادرست است یا پارامترها درست نیستند.
- InvalidTokenError: کلاس پایه برای دیگر خطاها.
from jwt import ExpiredSignatureError, InvalidTokenError
try:
decoded = jwt.decode(token, secret, algorithms=["HS256"])
except ExpiredSignatureError:
print("توکن منقضی شده است")
except InvalidTokenError:
print("توکن نامعتبر است")مدیریت دقیق استثناآت باعث میشود پاسخهای مناسب به کاربر برگردانده و لاگهای مفیدی ثبت کنید.
پارامترهای مفید در decode
- algorithms: فهرست الگوریتمهای مجاز (اجباری برای امنیت).
- audience و issuer: اعتبارسنجی audience و issuer برای جلوگیری از سوءاستفاده.
- leeway: برای تحمل اختلاف ساعت بین سرورها (مثلاً چند ثانیه).
- options: برای غیرفعال کردن/فعال کردن برخی بررسیها مثل verify_exp.
بهترین شیوهها و نکات امنیتی
- هرگز از الگوریتم “none” استفاده نکنید و همیشه پارامتر algorithms را مشخص کنید.
- رازها (secrets، private keys) را در متغیرهای محیطی یا سرویسهای مدیریت اسرار ذخیره کنید، نه در کد سورس.
- مدت عمر توکن را کوتاه نگه دارید و برای دسترسی طولانی از refresh token استفاده کنید.
- در صورت نیاز به لغو توکن، از لیست سیاه (revocation list) یا ذخیره نسخه (token identifier) در سرور استفاده کنید.
- برای انتقال حساس از توکنهای امضا شده بهعلاوه TLS (HTTPS) استفاده کنید.
مثال امنتر با expiration و audience
import os
import jwt
import datetime
SECRET = os.getenv("JWT_SECRET")
payload = {
"sub": "user123",
"aud": "my-api",
"iat": datetime.datetime.utcnow(),
"exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=15)
}
token = jwt.encode(payload, SECRET, algorithm="HS256")
decoded = jwt.decode(token, SECRET, algorithms=["HS256"], audience="my-api")در این قطعه، از متغیر محیطی برای کلید استفاده شده و audience بررسی میشود تا توکن تنها برای هدف مشخص معتبر باشد. زمان صدور (iat) و زمان انقضا (exp) نیز تعیین شدهاند.
جدول: الگوریتمهای رایج و نکات
| الگوریتم | نوع | نکات |
|---|---|---|
| HS256 | HMAC (متقارن) | ساده و سریع؛ کلید مشترک لازم است؛ مناسب برای سیستمهای داخلی |
| RS256 | RSA (نامتقارن) | امنتر برای توزیع؛ نیاز به کلید خصوصی و عمومی |
| ES256 | ECDSA (الگوریتم منحنی بیضوی) | کلیدهای کوچکتر، امنیت بالا، مناسب برای محیطهای حساس |
یک مثال پیشرفته: refresh token و revocation
معمولا از دو توکن استفاده میشود: access token کوتاهمدت و refresh token بلندمدت. هنگام لاگآوت یا تغییر رمز عبور، باید refresh tokenها را در سرور باطل کنید (مثلا ذخیره شناسه توکن در جدول revoked_tokens).
# شکل ساده از منطق revocation (pseudo)
# هنگام صدور
access_token = issue_access(payload)
refresh_token_id = store_refresh_token_in_db(user_id)
refresh_token = issue_refresh({"rid": refresh_token_id})
# هنگام استفاده از refresh
if is_revoked(refresh_token_id):
raise Unauthorized
# در غیر این صورت، توکن جدید صادر کندر این مثال شناسه refresh token در دیتابیس ذخیره و هنگام استفاده بررسی میشود. این روش امکان لغو دستی را فراهم میکند.
نتیجهگیری
PyJWT یک ابزار قدرتمند و ساده برای کار با JWT در پایتون است. رعایت نکات امنیتی مانند مشخص کردن الگوریتمها، مدیریت کلیدها، کوتاه نگهداشتن عمر توکن و پیادهسازی مکانیزم لغو، به شما کمک میکند تا از مزایای JWT بدون مخاطرات عمده بهرهمند شوید. برای استفاده در فریمورکهایی مانند Flask یا FastAPI معمولاً middlewareهایی وجود دارد که فرایند اعتبارسنجی را ساده میکنند؛ با این حال همیشه کنترل دقیق روی پارامترها و استثناها ضروری است.
آیا این مطلب برای شما مفید بود ؟




