美文网首页
Django 自定义用户认证

Django 自定义用户认证

作者: SateZheng | 来源:发表于2017-01-12 15:32 被阅读1450次

    官方文档:https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#substituting-a-custom-user-model

    Django 自带的用户认证系统已经可以满足大部分的情况,但也可以进行自定义来满足某些特定的需求。
    Django 支持使用其他的认证系统、也可以扩展Django的User模块,还可以完全自定义新的认证模块。

    定义用户认证模块,定义用户表的各个字段信息。

    写在单独的文件中(官方是写在models.py文件中,所以后边要在models.py导入该文件)

    # custom_auth.py
    from django.db import models
    from django.contrib.auth.models import (
        BaseUserManager, AbstractBaseUser
    )
    
    class MyUserManager(BaseUserManager):   # 定义创建登录用户和超级用户时需要的字段
        def create_user(self, email, name, password=None):
            """
            Creates and saves a User with the given email, date of
            birth and password.
            """
            if not email:
                raise ValueError('Users must have an email address')
    
            user = self.model(
                email=self.normalize_email(email),
                name=name,
            )
    
            user.set_password(password)
            user.save(using=self._db)
            return user
    
        def create_superuser(self, email, name, password):
            """
            Creates and saves a superuser with the given email, date of
            birth and password.
            """
            user = self.create_user(
                email,
                password=password,
                name=name,
            )
            user.is_admin = True
            user.save(using=self._db)
            return user
    
    
    class MyUser(AbstractBaseUser): # 定义自己的用户表
        email = models.EmailField(
            verbose_name='email address',
            max_length=255,
            unique=True,
        )
        name = models.DateField()
        is_active = models.BooleanField(default=True)
        is_admin = models.BooleanField(default=False)
    
        objects = MyUserManager()
    
        USERNAME_FIELD = 'email'    # 定义使用哪个字段作为用户名来登录
        REQUIRED_FIELDS = ['name']  # 不能为空的字段
    
        def get_full_name(self):
            # The user is identified by their email address
            return self.email
    
        def get_short_name(self):
            # The user is identified by their email address
            return self.email
    
        def __str__(self):              # __unicode__ on Python 2
            return self.email
    
        def has_perm(self, perm, obj=None):
            "Does the user have a specific permission?"
            # Simplest possible answer: Yes, always
            return True
    
        def has_module_perms(self, app_label):
            "Does the user have permissions to view the app `app_label`?"
            # Simplest possible answer: Yes, always
            return True
    
        @property
        def is_staff(self):
            "Is the user a member of staff?"
            # Simplest possible answer: All admins are staff
            return self.is_admin
    
    settings.py中添加AUTH_USER_MODEL = 'myapp.MyUser'
    AUTH_USER_MODEL = 'myapp.MyUser'
    

    如果要使用自定义的认证,必须在settings.py中指定使用的用户表。

    models.py文件中导入自定义的认证模块
    # models.py
    from custom_auth import UserProfile
    
    生成数据库
    $ python manage.py makemigrations
    $ python manage.py migrate 
    
    创建登录用户
    $ python manage.py createsuperuser
    
    Admin 的控制台

    admin.py中导入UserProfile

    from django.contrib import admin
    import models
    from custom_auth import UserProfile
    
    admin.site.register(models.UserProfile)
    

    这时,登录后台,就可以看到用户表。

    问题,登录后台时,发现用户的密码是明文显示的MD5值,而且创建了新用户,密码未进行加密处理,无法登录。

    使用Django的管理员注册此自定义用户模型

    admin.py 文件中

    from django import forms
    from django.contrib import admin
    from django.contrib.auth.models import Group
    from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
    from django.contrib.auth.forms import ReadOnlyPasswordHashField
    
    from customauth.models import MyUser
    
    
    class UserCreationForm(forms.ModelForm):
        """A form for creating new users. Includes all the required
        fields, plus a repeated password."""
        password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
        password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
    
        class Meta:
            model = MyUser
            fields = ('email', 'name')
    
        def clean_password2(self):
            # Check that the two password entries match
            password1 = self.cleaned_data.get("password1")
            password2 = self.cleaned_data.get("password2")
            if password1 and password2 and password1 != password2:
                raise forms.ValidationError("Passwords don't match")
            return password2
    
        def save(self, commit=True):
            # Save the provided password in hashed format
            user = super(UserCreationForm, self).save(commit=False)
            user.set_password(self.cleaned_data["password1"])
            if commit:
                user.save()
            return user
    
    
    class UserChangeForm(forms.ModelForm):
        """A form for updating users. Includes all the fields on
        the user, but replaces the password field with admin's
        password hash display field.
        """
        password = ReadOnlyPasswordHashField()
    
        class Meta:
            model = MyUser
            fields = ('email', 'password', 'name', 'is_active', 'is_admin')
    
        def clean_password(self):
            # Regardless of what the user provides, return the initial value.
            # This is done here, rather than on the field, because the
            # field does not have access to the initial value
            return self.initial["password"]
    
    
    class UserAdmin(BaseUserAdmin):
        # The forms to add and change user instances
        form = UserChangeForm
        add_form = UserCreationForm
    
        # The fields to be used in displaying the User model.
        # These override the definitions on the base UserAdmin
        # that reference specific fields on auth.User.
        list_display = ('email', 'name', 'is_admin')
        list_filter = ('is_admin',)
        fieldsets = (
            (None, {'fields': ('email', 'password')}),
            ('Personal info', {'fields': ('name',)}),
            ('Permissions', {'fields': ('is_admin',)}),
        )
        # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
        # overrides get_fieldsets to use this attribute when creating a user.
        add_fieldsets = (
            (None, {
                'classes': ('wide',),
                'fields': ('email', 'name', 'password1', 'password2')}
            ),
        )
        search_fields = ('email',)
        ordering = ('email',)
        filter_horizontal = ()
    
    # Now register the new UserAdmin...
    admin.site.register(MyUser, UserAdmin)
    # ... and, since we're not using Django's built-in permissions,
    # unregister the Group model from admin.
    admin.site.unregister(Group)
    
    

    相关文章

      网友评论

          本文标题:Django 自定义用户认证

          本文链接:https://www.haomeiwen.com/subject/cgndbttx.html