驗證與受權

Django有一個內置的受權系統:包括驗證和受權兩個部分。用來處理用戶、分組、權限以及基於cookie的會話系統。html

驗證:驗證這個用戶是不是他聲稱的人(好比用戶名和密碼驗證,角色驗證)python

受權:給與他相應的權限。數據庫

Django內置的權限系統:django

  1. 用戶。
  2. 權限。
  3. 分組。
  4. 一個能夠配置的密碼哈希系統。
  5. 一個可插拔的後臺管理系統。

 

受權系統:默認中建立完一個django項目後,就已經集成了受權系統。cookie

INSTALLED_APPSsession

  • django.contrib.auth:包含了一個核心受權框架,以及大部分的模型定義。
  • django.contrib.contenttypes:Content Type系統,能夠用來關聯模型和權限。

中間件框架

SessionMiddleware:用來管理session。
AuthenticationMiddleware:用來處理和當前session相關聯的用戶。post

 

User模型
網站

  該框架的核心部分。完整的路徑 django.contrib.auth.models.User ui

 

內置的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('我的中心,登陸才能查看!')
相關文章
相關標籤/搜索