|
|
import jwt |
|
|
import datetime |
|
|
from werkzeug.security import generate_password_hash, check_password_hash |
|
|
from flask import request, jsonify, current_app |
|
|
from functools import wraps |
|
|
import os |
|
|
|
|
|
class Authentication: |
|
|
def __init__(self): |
|
|
self.secret_key = os.getenv('JWT_SECRET_KEY', 'your-secret-key-here') |
|
|
self.algorithm = 'HS256' |
|
|
|
|
|
def generate_token(self, user_id, username, role='student'): |
|
|
"""تولید توکن JWT""" |
|
|
try: |
|
|
payload = { |
|
|
'exp': datetime.datetime.utcnow() + datetime.timedelta(days=7), |
|
|
'iat': datetime.datetime.utcnow(), |
|
|
'sub': user_id, |
|
|
'username': username, |
|
|
'role': role |
|
|
} |
|
|
return jwt.encode(payload, self.secret_key, algorithm=self.algorithm) |
|
|
except Exception as e: |
|
|
print(f"Token generation error: {e}") |
|
|
return None |
|
|
|
|
|
def verify_token(self, token): |
|
|
"""اعتبارسنجی توکن JWT""" |
|
|
try: |
|
|
payload = jwt.decode(token, self.secret_key, algorithms=[self.algorithm]) |
|
|
return payload |
|
|
except jwt.ExpiredSignatureError: |
|
|
print("Token expired") |
|
|
return None |
|
|
except jwt.InvalidTokenError: |
|
|
print("Invalid token") |
|
|
return None |
|
|
|
|
|
def hash_password(self, password): |
|
|
"""هش کردن رمز عبور""" |
|
|
return generate_password_hash(password) |
|
|
|
|
|
def check_password(self, hashed_password, password): |
|
|
"""بررسی تطابق رمز عبور""" |
|
|
return check_password_hash(hashed_password, password) |
|
|
|
|
|
def login_required(self, f): |
|
|
"""دکوراتور برای نیاز به احراز هویت""" |
|
|
@wraps(f) |
|
|
def decorated(*args, **kwargs): |
|
|
token = None |
|
|
|
|
|
|
|
|
if 'Authorization' in request.headers: |
|
|
auth_header = request.headers['Authorization'] |
|
|
try: |
|
|
token = auth_header.split(" ")[1] |
|
|
except IndexError: |
|
|
return jsonify({'message': 'Invalid token format'}), 401 |
|
|
|
|
|
if not token: |
|
|
return jsonify({'message': 'Token is missing'}), 401 |
|
|
|
|
|
|
|
|
payload = self.verify_token(token) |
|
|
if not payload: |
|
|
return jsonify({'message': 'Invalid token'}), 401 |
|
|
|
|
|
|
|
|
request.user_id = payload['sub'] |
|
|
request.username = payload['username'] |
|
|
request.user_role = payload['role'] |
|
|
|
|
|
return f(*args, **kwargs) |
|
|
return decorated |
|
|
|
|
|
|
|
|
auth_manager = Authentication() |