راهنمای جامع پیادهسازی مدلهای کاربری سفارشی در جنگو، بهبود احراز هویت برای نیازهای متنوع برنامههای جهانی. بهترین روشها و تکنیکهای پیشرفته را بیاموزید.
احراز هویت در پایتون جنگو: تسلط بر مدلهای کاربری سفارشی برای برنامههای جهانی
سیستم احراز هویت داخلی جنگو نقطه شروع قدرتمندی برای بسیاری از برنامههای وب است. با این حال، با مقیاسپذیر شدن و پیچیدهتر شدن برنامه شما، به ویژه برای مخاطبان جهانی، ممکن است مدل پیشفرض User کافی نباشد. اینجاست که مدلهای کاربری سفارشی وارد عمل میشوند و انعطافپذیری و کنترل بیشتری بر روی دادههای کاربر و فرآیندهای احراز هویت ارائه میدهند. این راهنمای جامع شما را در فرآیند ایجاد و پیادهسازی مدلهای کاربری سفارشی در جنگو راهنمایی میکند و تضمین میکند که برنامه شما برای مدیریت نیازهای متنوع کاربران و ملاحظات امنیتی به خوبی مجهز است.
چرا از یک مدل کاربری سفارشی استفاده کنیم؟
مدل پیشفرض User جنگو با ویژگیهای رایجی مانند نام کاربری، رمز عبور، ایمیل، نام و نام خانوادگی طراحی شده است. در حالی که برای برنامههای ساده مناسب است، اغلب زمانی که نیاز به موارد زیر دارید، کوتاه میآید:
- ذخیره اطلاعات اضافی کاربر: یک پلتفرم تجارت الکترونیک جهانی را در نظر بگیرید که نیاز به ذخیره ترجیحات کاربر، آدرسها در فرمتهای مختلف، ارزهای ترجیحی یا تنظیمات زبان دارد. این موارد فراتر از محدوده مدل پیشفرض هستند.
- تغییر فیلد احراز هویت: شاید بخواهید کاربران را با استفاده از آدرس ایمیل خود به جای نام کاربری احراز هویت کنید، یا احراز هویت چند عاملی را پیادهسازی کنید که به فیلدهای اضافی نیاز دارد.
- ادغام با پایگاههای داده موجود: اگر در حال ادغام یک برنامه جنگو با یک پایگاه داده موجود هستید که دارای اسکیمای کاربری متفاوتی است، یک مدل کاربری سفارشی به شما امکان میدهد مدل خود را با ساختار داده موجود نگاشت کنید.
- افزایش امنیت: مدلهای سفارشی کنترل بیشتری بر روی هش کردن رمز عبور، مکانیزمهای بازنشانی رمز عبور و سایر جنبههای مرتبط با امنیت را امکانپذیر میسازند.
- پیادهسازی نقشهای کاربری مختلف: ذخیره دادههای کنترل دسترسی مبتنی بر نقش (RBAC) به طور مستقیم در مدل (یا ارجاع به آن) کنترل انعطافپذیرتر و صریحتری نسبت به گروهها و مجوزهای عمومی ارائه میدهد.
استفاده از یک مدل کاربری سفارشی روشی تمیز و قابل نگهداری برای گسترش پروفایل کاربر بدون تغییر مستقیم سیستم احراز هویت اصلی جنگو فراهم میکند. این یک بهترین روش برای هر پروژهای است که رشد آینده را پیشبینی میکند یا به دادههای کاربری تخصصی نیاز دارد.
چه زمانی یک مدل کاربری سفارشی را پیادهسازی کنیم؟
بهترین زمان برای پیادهسازی یک مدل کاربری سفارشی در ابتدای پروژه شماست. تغییر مدل کاربری در یک محیط تولیدی میتواند پیچیده و به طور بالقوه به دادهها آسیب برساند. اگر پروژه شما از قبل در حال اجرا است، قبل از ایجاد هرگونه تغییر، پیامدهای آن را با دقت در نظر بگیرید و یک برنامه مهاجرت (migration) قوی ایجاد کنید.
در اینجا یک راهنمای کلی ارائه شده است:
- با یک مدل کاربری سفارشی شروع کنید: اگر هرگونه نیازی به اطلاعات کاربری گسترده یا منطق احراز هویت سفارشی را پیشبینی میکنید.
- مهاجرت را با دقت در نظر بگیرید: اگر از قبل یک پروژه جنگو در حال اجرا با کاربران دارید و تصمیم به تغییر به یک مدل سفارشی گرفتهاید. از پایگاه داده خود پشتیبان تهیه کنید و فرآیند مهاجرت را به طور کامل درک کنید.
ایجاد یک مدل کاربری سفارشی
دو رویکرد اصلی برای ایجاد یک مدل کاربری سفارشی در جنگو وجود دارد:
- AbstractBaseUser: این رویکرد به شما کنترل کاملی بر روی مدل کاربری میدهد. شما تمام فیلدها، از جمله نام کاربری، رمز عبور، ایمیل و هر فیلد سفارشی دیگری که نیاز دارید را تعریف میکنید.
- AbstractUser: این رویکرد از مدل پیشفرض User جنگو ارثبری میکند و به شما امکان میدهد فیلدهای موجود را اضافه یا بازنویسی کنید. این روش سادهتر است اگر فقط به اضافه کردن چند فیلد اضافی نیاز دارید.
۱. استفاده از AbstractBaseUser (کنترل کامل)
این انعطافپذیرترین گزینه است که به شما امکان میدهد کل مدل کاربری را از ابتدا تعریف کنید. این رویکرد بیشترین کنترل را بر ساختار داده کاربر و فرآیند احراز هویت فراهم میکند. در اینجا نحوه انجام آن آمده است:
مرحله ۱: ایجاد یک مدل کاربری سفارشی
در اپ جنگوی خود (مثلاً 'accounts')، یک فایل `models.py` ایجاد کنید و مدل کاربری سفارشی خود را با ارثبری از `AbstractBaseUser` و `PermissionsMixin` تعریف کنید:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager
class CustomUserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError('The Email field must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self.create_user(email, password, **extra_fields)
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True, verbose_name='email address')
first_name = models.CharField(max_length=150, blank=True)
last_name = models.CharField(max_length=150, blank=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(auto_now_add=True)
# Custom fields (Example: preferred language, timezone, etc.)
preferred_language = models.CharField(max_length=10, default='en', choices=[('en', 'English'), ('fr', 'French'), ('es', 'Spanish')])
timezone = models.CharField(max_length=50, default='UTC')
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = [] # Required when creating a superuser
objects = CustomUserManager()
def __str__(self):
return self.email
توضیحات:
- CustomUserManager: این کلاس برای مدیریت مدل کاربری سفارشی شما ضروری است. این کلاس ایجاد کاربران و ابرکاربران را مدیریت میکند. `normalize_email` برای اطمینان از یکپارچگی ایمیل در میان زبانها و روشهای ورودی مختلف مهم است.
- CustomUser: این مدل کاربری سفارشی شماست.
- `email = models.EmailField(unique=True, verbose_name='email address')`: فیلد ایمیل را به عنوان شناسه منحصر به فرد برای کاربر تعریف میکند. استفاده از `unique=True` تضمین میکند که هر کاربر یک آدرس ایمیل منحصر به فرد داشته باشد. نام گویا (verbose name) رابط کاربری ادمین را بهبود میبخشد.
- `first_name`, `last_name`: فیلدهای استاندارد برای ذخیره نام کاربر. `blank=True` به این فیلدها اجازه میدهد خالی باشند.
- `is_staff`, `is_active`: فیلدهای استاندارد برای کنترل دسترسی کاربر به پنل ادمین و فعالسازی حساب.
- `date_joined`: تاریخ ایجاد حساب کاربری را ثبت میکند.
- `preferred_language`, `timezone`: فیلدهای سفارشی نمونه برای ذخیره ترجیحات کاربر. آرگومان `choices` گزینههای زبان ممکن را محدود میکند. این برای یک برنامه جهانی حیاتی است. منطقه زمانی نیز برای بومیسازی مهم است.
- `USERNAME_FIELD = 'email'`: مشخص میکند که فیلد ایمیل به عنوان نام کاربری برای احراز هویت استفاده خواهد شد.
- `REQUIRED_FIELDS = []`: فیلدهایی را که هنگام ایجاد یک ابرکاربر با استفاده از دستور `createsuperuser` مورد نیاز هستند، مشخص میکند. در این مورد، هیچ فیلد اضافی به جز ایمیل و رمز عبور مورد نیاز نیست.
- `objects = CustomUserManager()`: مدیر کاربری سفارشی را به مدل اختصاص میدهد.
- `__str__(self)`: نحوه نمایش شیء کاربر به صورت رشتهای را تعریف میکند (مثلاً در پنل ادمین).
مرحله ۲: بهروزرسانی `settings.py`
با افزودن خط زیر به فایل `settings.py` خود، به جنگو بگویید که از مدل کاربری سفارشی شما استفاده کند:
AUTH_USER_MODEL = 'accounts.CustomUser'
`accounts` را با نام اپی که در آن مدل `CustomUser` را تعریف کردهاید، جایگزین کنید.
مرحله ۳: ایجاد و اعمال مایگریشنها (Migrations)
دستورات زیر را برای ایجاد و اعمال مایگریشنها اجرا کنید:
python manage.py makemigrations
python manage.py migrate
این کار یک جدول پایگاه داده جدید برای مدل کاربری سفارشی شما ایجاد میکند.
مرحله ۴: استفاده از مدل کاربری سفارشی
اکنون میتوانید از مدل کاربری سفارشی خود در ویوها، تمپلیتها و سایر بخشهای برنامه خود استفاده کنید. به عنوان مثال، برای ایجاد یک کاربر جدید:
from accounts.models import CustomUser
user = CustomUser.objects.create_user(email='user@example.com', password='password123', first_name='John', last_name='Doe')
۲. استفاده از AbstractUser (اضافه کردن به مدل پیشفرض)
این رویکرد سادهتر است اگر فقط نیاز به اضافه کردن چند فیلد اضافی به مدل پیشفرض User جنگو دارید. این روش تمام فیلدها و متدهای موجود را از `AbstractUser` به ارث میبرد. این میتواند برای سفارشیسازیهای سادهتر، آسانتر باشد.
مرحله ۱: ایجاد یک مدل کاربری سفارشی
در فایل `models.py` اپ جنگوی خود، مدل کاربری سفارشی خود را با ارثبری از `AbstractUser` تعریف کنید:
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
# Add extra fields here
phone_number = models.CharField(max_length=20, blank=True, verbose_name='Phone Number')
profile_picture = models.ImageField(upload_to='profile_pictures/', blank=True)
# Custom fields (Example: preferred currency, address format, etc.)
preferred_currency = models.CharField(max_length=3, default='USD', choices=[('USD', 'US Dollar'), ('EUR', 'Euro'), ('JPY', 'Japanese Yen')])
address_format = models.CharField(max_length=50, blank=True, help_text='e.g., "Name, Street, City, Zip, Country"')
def __str__(self):
return self.username
توضیحات:
- CustomUser: این مدل کاربری سفارشی شماست که از `AbstractUser` ارثبری میکند.
- `phone_number`, `profile_picture`: فیلدهای نمونه برای اضافه کردن به مدل کاربر. `upload_to` مشخص میکند که تصاویر پروفایل در کجا ذخیره خواهند شد.
- `preferred_currency`, `address_format`: فیلدهای سفارشی نمونه مرتبط با برنامههای جهانی. کشورهای مختلف فرمتهای آدرس کاملاً متفاوتی دارند.
- `__str__(self)`: نحوه نمایش شیء کاربر به صورت رشتهای را تعریف میکند (مثلاً در پنل ادمین). در اینجا از نام کاربری استفاده میکند.
مرحله ۲: بهروزرسانی `settings.py`
همانند قبل، با افزودن خط زیر به فایل `settings.py` خود، به جنگو بگویید که از مدل کاربری سفارشی شما استفاده کند:
AUTH_USER_MODEL = 'accounts.CustomUser'
مرحله ۳: ایجاد و اعمال مایگریشنها
دستورات زیر را برای ایجاد و اعمال مایگریشنها اجرا کنید:
python manage.py makemigrations
python manage.py migrate
مرحله ۴: استفاده از مدل کاربری سفارشی
اکنون میتوانید هنگام کار با اشیاء کاربر به فیلدهای اضافه شده دسترسی داشته باشید:
from accounts.models import CustomUser
user = CustomUser.objects.create_user(username='johndoe', password='password123', email='john.doe@example.com')
user.phone_number = '+15551234567'
user.preferred_currency = 'EUR'
user.save()
بهترین روشها برای مدلهای کاربری سفارشی در برنامههای جهانی
هنگام پیادهسازی مدلهای کاربری سفارشی برای برنامههایی که مخاطبان جهانی را هدف قرار میدهند، بهترین روشهای زیر را در نظر بگیرید:
۱. بینالمللیسازی و بومیسازی (i18n & l10n)
ذخیره دادههای مختص منطقه (Locale): مدل خود را طوری طراحی کنید که هنجارهای فرهنگی و فرمتهای داده مختلف را در خود جای دهد. تاریخها، زمانها، اعداد و آدرسها را به روشی آگاه از منطقه ذخیره کنید.
مثال:
from django.utils import timezone
class CustomUser(AbstractUser):
#...
date_of_birth = models.DateField(blank=True, null=True)
def get_localized_date_of_birth(self, language_code):
if self.date_of_birth:
return timezone.localtime(timezone.make_aware(datetime.datetime.combine(self.date_of_birth, datetime.time.min))).strftime('%x') # Format according to the locale
return None
۲. مدیریت منطقه زمانی (Timezone)
همیشه مناطق زمانی را به درستی ذخیره و مدیریت کنید. اطلاعات منطقه زمانی را در مدل کاربر ذخیره کنید و از آن برای نمایش تاریخها و زمانها در منطقه زمانی محلی کاربر استفاده کنید.
مثال:
from django.utils import timezone
class CustomUser(AbstractUser):
#...
timezone = models.CharField(max_length=50, default='UTC')
def get_localized_time(self, datetime_obj):
user_timezone = pytz.timezone(self.timezone)
return timezone.localtime(datetime_obj, user_timezone)
۳. قالببندی آدرس
فرمتهای آدرس در کشورهای مختلف به طور قابل توجهی متفاوت است. یک سیستم آدرس انعطافپذیر پیادهسازی کنید که به کاربران امکان میدهد آدرس خود را با فرمت صحیح برای مکان خود وارد کنند. استفاده از یک کتابخانه یا سرویس شخص ثالث برای مدیریت اعتبارسنجی و قالببندی آدرس را در نظر بگیرید.
مثال:
class CustomUser(AbstractUser):
#...
country = models.CharField(max_length=50, blank=True)
address_line_1 = models.CharField(max_length=255, blank=True)
address_line_2 = models.CharField(max_length=255, blank=True)
city = models.CharField(max_length=100, blank=True)
postal_code = models.CharField(max_length=20, blank=True)
def get_formatted_address(self):
# Implement logic to format address based on country
if self.country == 'US':
return f'{self.address_line_1}\n{self.address_line_2}\n{self.city}, {self.postal_code}, {self.country}'
elif self.country == 'GB':
return f'{self.address_line_1}\n{self.address_line_2}\n{self.city}\n{self.postal_code}\n{self.country}'
else:
return 'Address format not supported'
۴. مدیریت ارز
اگر برنامه شما شامل تراکنشهای مالی است، ارز ترجیحی کاربر را ذخیره کرده و از آن برای نمایش قیمتها و مبالغ استفاده کنید. از کتابخانهای مانند `babel` برای قالببندی مقادیر ارز بر اساس منطقه کاربر استفاده کنید.
مثال:
from babel.numbers import format_currency
class CustomUser(AbstractUser):
#...
preferred_currency = models.CharField(max_length=3, default='USD')
def get_formatted_price(self, amount):
return format_currency(amount, self.preferred_currency, locale='en_US') # Adjust locale as needed
۵. اعتبارسنجی دادهها
اعتبارسنجی قوی دادهها را برای اطمینان از معتبر و سازگار بودن ورودی کاربر پیادهسازی کنید. از اعتبارسنجهای داخلی جنگو یا اعتبارسنجهای سفارشی برای اجرای یکپارچگی دادهها استفاده کنید.
مثال:
from django.core.validators import RegexValidator
class CustomUser(AbstractUser):
#...
phone_number = models.CharField(
max_length=20,
blank=True,
validators=[
RegexValidator(
regex=r'^\+?\d{9,15}$',
message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed."
),
]
)
۶. ملاحظات امنیتی
هش کردن رمز عبور: سیستم احراز هویت جنگو به طور پیشفرض از الگوریتمهای قوی هش کردن رمز عبور استفاده میکند. اطمینان حاصل کنید که از آخرین نسخه جنگو استفاده میکنید تا از آخرین بهروزرسانیهای امنیتی بهرهمند شوید.
احراز هویت دو عاملی (2FA): برای افزودن یک لایه امنیتی اضافی به حسابهای کاربری، 2FA را پیادهسازی کنید. بستههای مختلف جنگو برای این منظور موجود است، مانند `django-otp`. این امر به ویژه هنگام مدیریت دادههای حساس کاربر یا تراکنشهای مالی مهم است.
حفاظت از دادهها: بهترین روشها برای حفاظت از دادهها و حریم خصوصی را دنبال کنید، به ویژه هنگام کار با اطلاعات حساس کاربر. با مقررات مربوط به حفاظت از دادهها، مانند GDPR و CCPA، مطابقت داشته باشید. تکنیکهای رمزگذاری دادهها، ناشناسسازی و توکنیزاسیون را در نظر بگیرید.
۷. تستنویسی
تستهای واحد و تستهای یکپارچهسازی جامعی بنویسید تا اطمینان حاصل کنید که مدل کاربری سفارشی شما همانطور که انتظار میرود کار میکند و سیستم احراز هویت شما امن است. سناریوهای مختلف، از جمله ورودیهای معتبر و نامعتبر کاربر، گردش کار بازنشانی رمز عبور و بررسی مجوزها را آزمایش کنید.
۸. مستندسازی
مدل کاربری سفارشی و سیستم احراز هویت خود را به طور کامل مستند کنید. این کار درک و نگهداری کد شما را برای سایر توسعهدهندگان آسانتر میکند. اطلاعاتی در مورد هدف هر فیلد، جریان احراز هویت و هرگونه ملاحظات امنیتی را شامل کنید.
تکنیکها و ملاحظات پیشرفته
۱. مدیران کاربری سفارشی (Custom User Managers)
همانطور که در مثال `AbstractBaseUser` نشان داده شد، مدیران کاربری سفارشی برای ایجاد و مدیریت کاربران ضروری هستند. آنها به شما امکان میدهند منطق سفارشی را برای ایجاد کاربران تعریف کنید، مانند تنظیم مقادیر پیشفرض برای فیلدهای خاص یا انجام اعتبارسنجی اضافی.
۲. مدلهای پروکسی (Proxy Models)
مدلهای پروکسی به شما امکان میدهند متدهایی را به مدل کاربر اضافه کنید بدون اینکه اسکیمای پایگاه داده را تغییر دهید. این میتواند برای اضافه کردن منطق سفارشی یا محاسباتی که مختص برنامه شما هستند مفید باشد.
۳. گسترش مدل کاربر با یک مدل پروفایل
به جای اضافه کردن فیلدهای زیاد به طور مستقیم به مدل کاربر، میتوانید یک مدل پروفایل جداگانه ایجاد کنید که با مدل کاربر رابطه یک به یک داشته باشد. این میتواند به تمیز و سازمانیافته نگه داشتن مدل کاربر شما کمک کند.
from django.db import models
from django.conf import settings
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='profile')
# Additional fields
bio = models.TextField(blank=True)
location = models.CharField(max_length=100, blank=True)
به یاد داشته باشید که یک سیگنال برای ایجاد خودکار یک UserProfile هنگام ایجاد یک کاربر ایجاد کنید:
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings
from .models import UserProfile
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
۴. ورود یکپارچه (Single Sign-On - SSO)
برای سازمانهای بزرگتر یا برنامههایی که نیاز به ادغام با سایر سرویسها دارند، پیادهسازی ورود یکپارچه (SSO) با استفاده از پروتکلهایی مانند OAuth 2.0 یا SAML را در نظر بگیرید. جنگو چندین بسته ارائه میدهد که ادغام SSO را ساده میکند، مانند `django-allauth`.
۵. ثبت وقایع حسابرسی (Audit Logging)
ثبت وقایع حسابرسی را برای ردیابی فعالیت کاربر و تغییرات در دادههای کاربر پیادهسازی کنید. این میتواند برای نظارت امنیتی، انطباق با مقررات و اشکالزدایی مفید باشد. بستههایی مانند `django-auditlog` میتوانند به خودکارسازی این فرآیند کمک کنند.
نتیجهگیری
ایجاد و پیادهسازی مدلهای کاربری سفارشی در جنگو انعطافپذیری و کنترلی را که برای ساخت سیستمهای احراز هویت قوی و مقیاسپذیر، به ویژه برای برنامههای جهانی، نیاز دارید، فراهم میکند. با دنبال کردن بهترین روشهای ذکر شده در این راهنما، میتوانید اطمینان حاصل کنید که برنامه شما برای مدیریت نیازهای متنوع کاربران، حفظ یکپارچگی دادهها و ارائه یک تجربه امن و کاربرپسند برای کاربران در سراسر جهان به خوبی مجهز است. به یاد داشته باشید که پیادهسازی خود را با دقت برنامهریزی کنید، نیازهای کاربران خود را در نظر بگیرید و امنیت را در هر مرحله از فرآیند در اولویت قرار دهید. انتخاب بین `AbstractBaseUser` و `AbstractUser` به سطح سفارشیسازی مورد نیاز بستگی دارد. برای تغییرات قابل توجه، `AbstractBaseUser` کنترل بیشتری را ارائه میدهد. برای افزونههای ساده، `AbstractUser` یک انتقال روانتر را فراهم میکند. تستنویسی کامل برای اطمینان از اینکه مدل کاربری سفارشی به طور یکپارچه با بقیه برنامه جنگوی شما ادغام شده و تمام الزامات امنیتی را برآورده میکند، حیاتی است. بهترین روشها برای بینالمللیسازی، بومیسازی و مدیریت منطقه زمانی را برای ارائه یک تجربه واقعاً جهانی به کار بگیرید. این امر به طور قابل توجهی به موفقیت و پذیرش برنامه شما در بازارهای متنوع در سراسر جهان کمک خواهد کرد.