验证与授权

Django有一个内置的授权系统:包括验证和授权两个部分。用来处理用户、分组、权限以及基于cookie的会话系统。

验证:验证这个用户是否是他声称的人(比如用户名和密码验证,角色验证)

授权:给与他相应的权限。

Django内置的权限系统:

  1. 用户。
  2. 权限。
  3. 分组。
  4. 一个可以配置的密码哈希系统。
  5. 一个可插拔的后台管理系统。

 

授权系统:默认中创建完一个django项目后,就已经集成了授权系统。

INSTALLED_APPS

  • django.contrib.auth:包含了一个核心授权框架,以及大部分的模型定义。
  • django.contrib.contenttypes:Content Type系统,可以用来关联模型和权限。

中间件

SessionMiddleware:用来管理session。
AuthenticationMiddleware:用来处理和当前session相关联的用户。

 

User模型

  该框架的核心部分。完整的路径 django.contrib.auth.models.User 

 

内置的User模型拥有的字段:

  • username: 用户名。150个字符以内。可以包含数字和英文字符,以及_、@、+、.和-字符。不能为空,且唯一!
  • first_name:在30个字符以内。可为空。
  • last_name:在150个字符以内。可为空。
  • email:邮箱。可为空。
  • password:密码。经过哈希过后的密码。
  • groups:分组。一个用户可以属于多个分组,一个分组可以拥有多个用户。groups这个字段是跟Group的一种多对多的关系。
  • user_permissions:权限。一个用户可以拥有多个权限,一个权限可以被多个用户所有用。和Permission属于一种多对多的关系。
  • is_staff:是否可以进入到admin的站点。代表是否是员工。
  • is_active:是否是可用的。对于一些想要删除账号的数据,我们设置这个值为False就可以了,而不是真正的从数据库中删除。
  • is_superuser:是否是超级管理员。如果是,那么拥有整个网站的所有权限。
  • last_login:上次登录的时间。
  • date_joined:账号创建的时间。

基本用法:

  • 创建用户:通过 create_user 方法创建用户。该方法必须要传递 usernameemailpassword;
  • 创建超级用户:
    1. 代码的方式。与创建普通用户类似,需使用 create_superuser ;
    2. 命令行的方式: python manage.py createsuperuser
1 from django.http import HttpResponse
2 from django.contrib.auth.models import User
3 
4 def index(request):
5     # 创建普通用户
6     user = User.objects.create_user(username='jack',email='jack@123.com',password='111111')
7     # 创建超级用户
8     user = User.objects.create_superuser(username='Alen', email='Alen@123.com', password='111111')
9     return HttpResponse('success')

 

修改密码:

  密码是需要经过加密后才能存储进去的。不能直接修改 password 字段,需要调用 set_password 来修改密码。

1 user = User.objects.get(pk=1)
2 user.set_password('填写新密码')
3 user.save()

 

登录验证:

  Django的验证系统已经通过 django.contrib.auth.authenticate 实现了登录验证的功能。该方法只能通过 username 和 password 来进行验证。

 1 from django.contrib.auth import authenticate
 2 
 3 def index(request):
 4     username = 'jack'
 5     password = '111111'
 6     user = authenticate(request,username=username,password=password)
 7     if user:
 8         print('登录成功:%s'% username)
 9     else:
10         print('用户名或密码错误!')
11     return HttpResponse('success')

 

扩展用户模型:

  在验证用户登录的时候,用的是用户名作为验证,而有时候需要通过手机号码或者邮箱来进行验证。或者需要增加一些新的字段。这时就需要扩展用户模型。

 

  • 设置Proxy模型:对Django提供的字段,以及验证的方法没有需要改的,只需要在原有的基础之上增加一些操作的方法。使用这种方式。
     1 from django.db import models
     2 from django.contrib.auth.models import User
     3 
     4 # 使用代理模型,不能添加新的Field;可加新属性;
     5 class Person(User):
     6     class Meta:
     7         proxy = True
     8     #增加黑名单属性;
     9     @classmethod
    10     def get_blacklsit(cls):
    11         return cls.objects.filter(is_active=False)
     1 from .models import Person
     2 from django.contrib.auth.models import User
     3 from django.http import HttpResponse
     4 
     5 # 提取数据表单中“is_active=0”的黑名单数据;(‘auth_user’表单已存储数据)
     6 def get_blacklist(request):
     7     black_list = Person.get_blacklsit()
     8     for person in black_list:
     9         print(person.username)
    10     return HttpResponse('proxy')

    定义了一个 Person类 ,继承自 User ,Meta 中设置 proxy=True ,说明这只是 User 的一个代理模型。不影响原来User模型在数据库中表的结构。且 User.objects.all() 和 Person.objects.all() 是等价的。都是从User这个模型中获取所有的数据。

     

  • 一对一外键:对用户验证方法 authenticate 不满足,需要在原来模型的基础上添加新的字段。
     1 from django.db import models
     2 from django.contrib.auth.models import User
     3 from django.dispatch import receiver
     4 from django.db.models.signals import post_save
     5 
     6 # 使用一对一外键扩展
     7 class UserExtension(models.Model):
     8     user = models.OneToOneField(User,on_delete=models.CASCADE,related_name='extension')
     9     telephone = models.CharField(max_length=11)
    10     school = models.CharField(max_length=100)
    11 
    12 # @receiver:用于将接收器连接到信号的装饰器。通过传入使用信号(或信号列表)和连接的关键字参数;
    13 # sender:发送者 ;  instance:调用save的实例 ;  created:是否是新创建的;
    14 # 接收User的save信号;
    15 @receiver(post_save,sender=User)
    16 def handler_user_extension(sender,instance,created,**kwargs):
    17     if created:
    18         UserExtension.objects.create(user=instance)
    19     else:
    20         instance.extension.save()
     1 from django.shortcuts import render
     2 from django.http import HttpResponse
     3 from django.contrib.auth import authenticate
     4 from .models import UserExtension
     5 from django.contrib.auth.models import User
     6 
     7 # 自定义验证号码及密码;
     8 def my_authenticate(telephone,password):
     9     user = User.objects.filter(extension__telephone=telephone).first()
    10     if user:
    11         is_correct = user.check_password(password)
    12         if is_correct:
    13             return user
    14         else:
    15             return None
    16     else:
    17         return None
    18 
    19 def one_view(request):
    20     # 创建用户,使用外键反向引用添加telephone;
    21     # user = User.objects.create_user(username='three',password='111111',email='three@123.com')
    22     # user.extension.telephone = '18988889999'
    23     # user.save()
    24     # 进行验证;
    25     telephone = request.GET.get('telephone')
    26     password = request.GET.get('password')
    27     user = my_authenticate(telephone,password)
    28     if user:
    29         print('%s:验证成功'% user.username)
    30     else:
    31         print('用户验证失败!')
    32     return HttpResponse('success')

    定义一个 UserExtension的模型 与 User模型 进行一对一的绑定,以后新增的字段,就添加到 UserExtension 上。创建一个接受保存模型的信号处理方法,只要 User 调用了 save 方法,就会创建一个 UserExtension 和 User 进行绑定。

 

登录、注销和登录限制

登录用户:

 1 from django.contrib.auth import login
 2 
 3 def my_login(request):
 4     if request.method == 'GET':
 5         return render(request,'login.html')
 6     else:
 7         form = LoginForm(request.POST)
 8         if form.is_valid():
 9             telephone = form.cleaned_data.get('telephone')
10             password = form.cleaned_data.get('password')
11             remember = form.cleaned_data.get('remember')
12             user = my_authenticate(telephone=telephone,password=password)
13             if user and user.is_active:
14                 # 判断通过时登录成功,会生成session数据;再判断是否记住数据;
15                 login(request,user)
16                 if remember:
17                     request.session.set_expiry(None)
18                 else:
19                     request.session.set_expiry(0)
20                 # 定义获取next时的跳转页面
21                 next_url = request.GET.get('next')
22                 if next_url:
23                     return redirect(next_url)
24                 else:
25                     return HttpResponse('登录成功')
26             else:
27                 return HttpResponse('手机号或密码错误!')
28         else:
29             print(form.errors)
30             return redirect(reverse('login'))
1 <!--login.html-->
2 <tr>
3     <td>
4         <label for="">
5         <input type="checkbox" name="remember" value="1">记住密码
6     </label>
7     </td>
8 </tr>

 

注销用户:

1 from django.contrib.auth import logout
2 
3 # 注销用户
4 def my_logout(request):
5     logout(request)
6     return HttpResponse('退出登录')

登录限制:

1 from django.contrib.auth.decorators import login_required
2 
3 # 登录限制,验证失败是会跳转到‘/login/’的url页面;
4 @login_required(login_url='/login/')
5 def profile(request):
6     return HttpResponse('个人中心,登录才能查看!')

 

posted @ 2019-04-21 22:20  F·灬小人物  阅读(465)  评论(0编辑  收藏  举报