Initial commit - clean project structure
This commit is contained in:
60
accounts/authentication.py
Normal file
60
accounts/authentication.py
Normal file
@@ -0,0 +1,60 @@
|
||||
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
|
||||
Reference in New Issue
Block a user