ساخت سیستم احراز هویت با JWT در پایتون
این مقاله به آموزش گام به گام ساخت یک سیستم احراز هویت امن با استفاده از JSON Web Tokens (JWT) در پایتون میپردازد. JWT یک استاندارد باز برای انتقال اطلاعات به صورت امن بین طرفین به عنوان یک شیء JSON است. این روش به طور گستردهای در احراز هویت و مجوزدهی استفاده میشود. این آموزش در دسته بندی ‘امنیت و رمزنگاری در پایتون’ قرار میگیرد و برای توسعهدهندگانی که به دنبال پیادهسازی یک سیستم احراز هویت قوی و مقیاسپذیر هستند، مناسب است.
مقدمه بر JWT
JWT یک رشته متنی است که به صورت رمزنگاری شده اطلاعات را حمل میکند. این اطلاعات قابل اعتماد هستند زیرا با یک کلید مخفی امضا شدهاند. JWT شامل سه بخش اصلی است:
- Header: اطلاعاتی در مورد نوع توکن و الگوریتم امضا را مشخص میکند.
- Payload: حاوی اطلاعاتی است که میخواهیم منتقل کنیم (مانند شناسه کاربر، نقشها و غیره).
- Signature: با استفاده از کلید مخفی و الگوریتم مشخص شده در Header ایجاد میشود و برای تأیید اصالت توکن استفاده میشود.
JWT به دلیل حجم کم، قابلیت حمل آسان و عدم نیاز به ذخیره اطلاعات session در سمت سرور، یک انتخاب محبوب برای احراز هویت است.
پیشنیازها
برای دنبال کردن این آموزش، به موارد زیر نیاز دارید:
- پایتون (نسخه 3.6 یا بالاتر)
- Flask (یا هر فریمورک وب پایتون دیگر)
- کتابخانه PyJWT
میتوانید کتابخانه PyJWT را با استفاده از pip نصب کنید:
pip install PyJWT
گام اول: نصب و پیکربندی Flask
ابتدا یک پروژه Flask جدید ایجاد کنید. اگر Flask را نصب ندارید، آن را با استفاده از pip نصب کنید:
pip install Flask
سپس یک فایل پایتون (مثلاً app.py) ایجاد کنید و کد زیر را در آن قرار دهید:
from flask import Flask, request, jsonify
app = Flask(__name__)
# کلید مخفی برای امضای JWT
app.config['SECRET_KEY'] = 'your-secret-key'
@app.route('/')
def index():
return "سیستم احراز هویت با JWT"
if __name__ == '__main__':
app.run(debug=True)
توجه: کلید مخفی (SECRET_KEY) را با یک رشته تصادفی و قوی جایگزین کنید. این کلید برای امضای JWT استفاده میشود و نباید در معرض دید قرار گیرد.
گام دوم: ایجاد Endpoint برای ثبت نام (Registration)
Endpoint ثبت نام مسئول دریافت اطلاعات کاربر (مانند نام کاربری و رمز عبور) و ذخیره آن در پایگاه داده است. برای سادگی، در این آموزش از یک لیست پایتون به عنوان پایگاه داده استفاده میکنیم.
users = []
@app.route('/register', methods=['POST'])
def register():
data = request.get_json()
username = data.get('username')
password = data.get('password')
# بررسی وجود نام کاربری تکراری
for user in users:
if user['username'] == username:
return jsonify({'message': 'نام کاربری قبلاً وجود دارد'}), 400
# ذخیره اطلاعات کاربر
user = {'username': username, 'password': password}
users.append(user)
return jsonify({'message': 'ثبت نام با موفقیت انجام شد'}), 201
گام سوم: ایجاد Endpoint برای ورود (Login)
Endpoint ورود مسئول دریافت نام کاربری و رمز عبور، بررسی اعتبار آنها و در صورت صحت، ایجاد و بازگرداندن یک JWT است.
import jwt
import datetime
@app.route('/login', methods=['POST'])
def login():
data = request.get_json()
username = data.get('username')
password = data.get('password')
# بررسی اعتبار کاربر
for user in users:
if user['username'] == username and user['password'] == password:
# ایجاد JWT
payload = {
'username': username,
'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=30) # اعتبار توکن 30 دقیقه
}
token = jwt.encode(payload, app.config['SECRET_KEY'], algorithm='HS256')
return jsonify({'token': token}), 200
return jsonify({'message': 'نام کاربری یا رمز عبور اشتباه است'}), 401
در این کد:
- `jwt.encode()` برای ایجاد JWT استفاده میشود.
- `payload` حاوی اطلاعاتی است که میخواهیم در JWT ذخیره کنیم (در اینجا نام کاربری و زمان انقضا).
- `app.config[‘SECRET_KEY’]` کلید مخفی برای امضای JWT است.
- `algorithm=’HS256’` الگوریتم امضا را مشخص میکند.
- `exp` زمان انقضای توکن را مشخص میکند.
گام چهارم: ایجاد Endpoint محافظت شده (Protected)
Endpoint محافظت شده فقط باید توسط کاربرانی که JWT معتبری دارند قابل دسترسی باشد. برای این منظور، باید JWT را از درخواست دریافت کرده و آن را تأیید کنیم.
@app.route('/protected', methods=['GET'])
def protected():
token = request.headers.get('Authorization')
if not token:
return jsonify({'message': 'توکن ارائه نشده است'}), 401
try:
# تأیید JWT
payload = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])
username = payload['username']
return jsonify({'message': f'دسترسی مجاز برای کاربر {username}'}), 200
except jwt.ExpiredSignatureError:
return jsonify({'message': 'توکن منقضی شده است'}), 401
except jwt.InvalidTokenError:
return jsonify({'message': 'توکن نامعتبر است'}), 401
در این کد:
- `request.headers.get(‘Authorization’)` برای دریافت JWT از هدر Authorization درخواست استفاده میشود.
- `jwt.decode()` برای تأیید JWT استفاده میشود.
- در صورت تأیید JWT، اطلاعات کاربر از `payload` استخراج میشود.
- در صورت بروز خطا (مانند انقضای توکن یا نامعتبر بودن توکن)، یک پیام خطا بازگردانده میشود.
تست سیستم
برای تست سیستم، میتوانید از ابزارهایی مانند Postman یا curl استفاده کنید.
- ثبت نام: یک درخواست POST به `/register` با بدنه JSON حاوی نام کاربری و رمز عبور ارسال کنید.
- ورود: یک درخواست POST به `/login` با بدنه JSON حاوی نام کاربری و رمز عبور ارسال کنید. پاسخ شامل JWT خواهد بود.
- دسترسی به Endpoint محافظت شده: یک درخواست GET به `/protected` با هدر `Authorization` حاوی JWT ارسال کنید.
نکات امنیتی
در هنگام پیادهسازی سیستم احراز هویت با JWT، نکات امنیتی زیر را در نظر داشته باشید:
- کلید مخفی: کلید مخفی را به صورت امن ذخیره کنید و از افشای آن جلوگیری کنید.
- الگوریتم امضا: از یک الگوریتم امضای قوی مانند HS256 یا RS256 استفاده کنید.
- زمان انقضا: برای JWT یک زمان انقضای مناسب تعیین کنید.
- ذخیره رمز عبور: رمز عبور کاربران را به صورت هش شده و با استفاده از یک الگوریتم قوی ذخیره کنید.
- اعتبارسنجی ورودی: ورودیهای کاربر را به دقت اعتبارسنجی کنید تا از حملات تزریقی جلوگیری کنید.
نتیجهگیری
این مقاله یک راهنمای جامع برای ساخت یک سیستم احراز هویت با JWT در پایتون ارائه داد. با استفاده از این روش، میتوانید یک سیستم احراز هویت امن و مقیاسپذیر برای برنامههای وب خود ایجاد کنید. به یاد داشته باشید که نکات امنیتی را رعایت کنید تا از حملات احتمالی جلوگیری کنید.

بدون دیدگاه