Files
MathApp/accounts/authentication.py

61 lines
2.0 KiB
Python

from django.conf import settings
from django.core import signing
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from .models import User
ACCESS_TOKEN_SALT = 'tadrisino-access-token'
def issue_access_token(user_id: int) -> str:
"""
ساخت access token امضاشده (stateless) — دیتابیس ذخیره نمی‌شه، فقط
امضا و expiry داره. با django.core.signing (بدون نیاز به کتابخونه‌ی JWT).
"""
signer = signing.TimestampSigner(salt=ACCESS_TOKEN_SALT)
return signer.sign(str(user_id))
def decode_access_token(token: str) -> int:
signer = signing.TimestampSigner(salt=ACCESS_TOKEN_SALT)
try:
value = signer.unsign(token, max_age=settings.ACCESS_TOKEN_TTL_SECONDS)
except signing.SignatureExpired:
raise AuthenticationFailed('توکن منقضی شده است.')
except signing.BadSignature:
raise AuthenticationFailed('توکن نامعتبر است.')
return int(value)
class TadrisinoTokenAuthentication(BaseAuthentication):
"""
هدر مورد انتظار: Authorization: Bearer <access_token>
اگه هدر نباشه، درخواست به‌صورت anonymous ادامه پیدا می‌کنه (None, None)
و View خودش تصمیم می‌گیره که آیا auth اجباریه (IsAuthenticated) یا نه.
"""
keyword = 'Bearer'
def authenticate(self, request):
auth_header = request.headers.get('Authorization', '')
if not auth_header:
return None
parts = auth_header.split()
if len(parts) != 2 or parts[0] != self.keyword:
return None
token = parts[1]
user_id = decode_access_token(token)
try:
user = User.objects.get(pk=user_id)
except User.DoesNotExist:
raise AuthenticationFailed('کاربر پیدا نشد.')
return (user, token)
def authenticate_header(self, request):
return self.keyword