43)django-用户认证,授权,自定义用户认证

##用户认证
    django自带用户认证系统,包括认证和授权。用户认证系统由用户,权限,用户组,密码,cookie和session给组成。
###用户认证系统设置
    #settings.py
     INSTALLED_APPS中设置

        django.contrib.auth
        django.contrib.contenttypes
    MIDDLEWARE 中设置
        AuthenticationMiddleware 

###用户默认功能
    1)私有属性
    username
    password
    email
    first_name
    last_name

    2)创建普通用户
        from django.contrib.auth.models import User
        user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
    
    3)创建管理员
        python manage.py createsuperuser --username=joe --email=joe@example.com

    4)修改密码
        from django.contrib.auth.models import User
        u = User.objects.get(username='john')
        u.set_password('new password')
        u.save()

    5)验证用户
        from django.contrib.auth import authenticate
        user = authenticate(username='john', password='secret')
        if user is not None:
            #验证成功
        else:
            # 验证失败

    6)权限和授权
        has_add_permission() #增加权限
        has_change_permission()#修改权限
        has_delete_permission()#删除权限

        myuser.groups.set([group_list])
        myuser.groups.add(group, group, ...)
        myuser.groups.remove(group, group, ...)
        myuser.groups.clear()
        myuser.user_permissions.set([permission_list])
        myuser.user_permissions.add(permission, permission, ...)
        myuser.user_permissions.remove(permission, permission, ...)
        myuser.user_permissions.clear()

    7)默认权限在python manage.py migrate创建

    8)添加自定义权限
        比如应用名:foo 模板名: Bar
        添加: user.has_perm('foo.add_bar')
        修改: user.has_perm('foo.change_bar')
        删除: user.has_perm('foo.delete_bar')


    9)验证成功登陆
        from django.contrib.auth import authenticate, login
        
        def my_view(request):
            username = request.POST['username']
            password = request.POST['password']
            user = authenticate(request, username=username, password=password)
            if user is not None:
                login(request, user)
                # Redirect to a success page.
                ...
            else:
                # Return an 'invalid login' error message.
                ...

    10)检查是登陆成功(session)
        if request.user.is_authenticated:
            # Do something for authenticated users.
            ...
        else:
            # Do something for anonymous users.

    11)登出
        from django.contrib.auth import logout
        def logout_view(request):
            logout(request)        

    12)用装饰器验证是否登陆成功  
        from django.contrib.auth.decorators import login_required
        @login_required
        def my_view(request):
        
        #如果没有设置settings.LOGIN_URL,就验证没有成功,默认会跳转 
        比如 /accounts/login/?next=/polls/3/ next是你验证的页面,如果页面验证成功会还回next页面

    
        from django.contrib.auth.decorators import login_required
        #验证成功跳到指定的页面
        @login_required(login_url='/accounts/login/')
        @login_required(redirect_field_name='my_redirect_field')
        def my_view(request):


    13)限制某些用户登陆
        from django.shortcuts import redirect
        
        def my_view(request):
            if not request.user.email.endswith('@example.com'):
                return redirect('/login/?next=%s' % request.path)

    14)修改密码
        from django.contrib.auth import update_session_auth_hash
        
        def password_change(request):
            if request.method == 'POST':
                form = PasswordChangeForm(user=request.user, data=request.POST)
                if form.is_valid():
                    form.save()
                    update_session_auth_hash(request, form.user)
            else:
                ...
        ##
        <form method="post" action="{% url 'login' %}">
        {% csrf_token %}
        <table>
        <tr>
            <td>{{ form.username.label_tag }}</td>
            <td>{{ form.username }}</td>
        </tr>
        <tr>
            <td>{{ form.password.label_tag }}</td>
            <td>{{ form.password }}</td>
        </tr>
        </table>
        
        <input type="submit" value="login" />
        <input type="hidden" name="next" value="{{ next }}" />
        </form>

    15)默认URL
        accounts/login/ [name='login']
        accounts/logout/ [name='logout']
        accounts/password_change/ [name='password_change']
###定制用户认证

    示例:
    #在model里面写入,字段可以该成需要的
    from django.db import models
    from django.contrib.auth.models import (
        BaseUserManager, AbstractBaseUser
    )
    
    
    class MyUserManager(BaseUserManager):
        def create_user(self, email, date_of_birth, 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),
                date_of_birth=date_of_birth,
            )
    
            user.set_password(password)
            user.save(using=self._db)
            return user
    
        def create_superuser(self, email, date_of_birth, password):
            """
            Creates and saves a superuser with the given email, date of
            birth and password.
            """
            user = self.create_user(
                email,
                password=password,
                date_of_birth=date_of_birth,
            )
            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,
        )
        date_of_birth = models.DateField()
        is_active = models.BooleanField(default=True)
        is_admin = models.BooleanField(default=False)
    
        objects = MyUserManager()
    
        USERNAME_FIELD = 'email'
        REQUIRED_FIELDS = ['date_of_birth']
    
        def __str__(self):
            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

    #注册admin
    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', 'date_of_birth')
    
        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().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', 'date_of_birth', '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', 'date_of_birth', 'is_admin')
        list_filter = ('is_admin',)
        fieldsets = (
            (None, {'fields': ('email', 'password')}),
            ('Personal info', {'fields': ('date_of_birth',)}),
            ('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', 'date_of_birth', '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)


    #在setting中设置使用那个认证类
    settings.py:
    
    AUTH_USER_MODEL = 'customauth.MyUser'

 

posted on 2018-02-25 14:20  shisanjun  阅读(1258)  评论(0编辑  收藏  举报

导航