認證登陸(附方法實現代碼,百度網盤拉取即可下載,激活碼:gqt1)
在進行用戶登陸驗證的時候,如果是自己寫代碼,就必須要先查詢數據庫,看用戶輸入的用戶名是否存在於數據庫中; 如果用戶存在於數據庫中,然后再驗證用戶輸入的密碼,這樣一來就要自己編寫大量的代碼。 事實上,Django已經提供了內置的用戶認證功能。
在使用"python manage.py makemigrationss"和"python manage.py migrate"遷移完成數據庫之后 根據配置文件settings.py中的數據庫段生成的數據表中已經包含了6張進行認證的數據表,分別是 auth_user auth_group auth_group_permissions auth_permission auth_user_groups auth_user_user_permissions 進行用戶認證的數據表為auth_user 要使用Django自帶的認證功能,首先要導入auth模塊
Django從開始就帶有一個用戶認證系統;它處理用戶賬號、組、權限以及基於cookie的用戶會話。 Django認證系統同時處理認證和授權。簡單地講,認證驗證一個用戶是否它們聲稱的那個人, 授權決定一個通過了認證的用戶被允許做什么。這里的詞語“認證”同時指代這兩項任務。 認證系統包含: 用戶。 權限:二元(是/否)標志指示一個用戶是否可以做一個特定的任務。 組:對多個用戶運用標簽和權限的一種通用的方式。
我們先來看看User表的結構:

1,is_authenticated()
這個認證的方法,驗證是否通過,也就是通過用戶名和密碼判斷該用戶是否存在。 2,is_anonymous()
方法也常用,判斷是否為匿名用戶,如果你已經login,則這個方法返回始終為false。 3,is_staff 是否為staff身份,布爾值。擁有staff身份的用戶可以登錄django的admin后台 4,is_superuser 是否是superuser身份,布爾值。擁有該身份的用戶將能夠登錄admin后台,並擁有所有注冊模型的管理權限。 5,last_login 用戶最后登錄的時間。 6,date_joine 用戶創建的時間。
接下來我們看具體的代碼方法實現:
1,創建用戶
第一種使用manage.py創建用戶,這創建的是一個超級用戶:
python manage.py createsuperuser #創建超級用戶
python manage.py changepassword admin #修改超級用戶密碼
第二種是創建普通用戶,
from django.contrib.auth.models import User User.objects.create_user(username=username, password=password2) #User對象屬性:username,password為必填項password用哈希算法保存到數據庫中
2,更改密碼
from django.contrib.auth.models import User u = User.objects.get(username='dkey') # set_password函數,設置密碼; u.set_password('123456') # check_password函數,檢查密碼; u.check_password('123456') True # save函數,保存密碼; u.save()
3,認證用戶
from django.contrib.auth import authenticate
user = authenticate(username='dkey', password='123456') if user is not None: # the password verified for the user if user.is_active: print("User is valid, active and authenticated") else: print("The password is valid, but the account has been disabled!") else: # the authentication system was unable to verify the username and password print("The username and password were incorrect.")
4,登錄
如果你有一個認證了的用戶,你想把它附帶到當前的會話中 – 這可以通過login()
函數完成。
從視圖中登入一個用戶,請使用login()
。它接受一個HttpRequest對象和一個User對象。login()
使用Django的session框架來用戶的ID保存在session中。
注意,任何在匿名會話中設置的數據都會在用戶登入后的會話中都會記住。
from django.contrib.auth import authenticate, login def my_view(request): username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password) if user is not None: if user.is_active: login(request, user) # Redirect to a success page. else: # Return a 'disabled account' error message ... else: # Return an 'invalid login' error message. ...
login()
做的事情就有給該用戶設置session信息的,保證后面驗證用戶是否認證通過。
5,登出
若要登出一個已經通過django.contrib.auth.login()
登入的用戶,可以在你的視圖中使用django.contrib.auth.logout()
。
它接收一個HttpRequest對象且沒有返回值。例如:
def logout_view(request):#登出 logout(request) #當調用該函數時,當前請求的session信息全部被清除,即使當前用戶沒有登陸,調用該函數也不會報錯。 return redirect('/')
注意,即使用戶沒有登入,login()
也不會拋出任何錯誤。
6,只允許登錄的用戶訪問
from django.conf import settings from django.shortcuts import redirect def my_view(request): if not request.user.is_authenticated(): return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path)) else: do_something()
使用login_required裝飾器
舉個例子比如用戶沒有登錄的情況下訪問用戶中心:
from django.utils.decorators import method_decorator #類裝飾方法 from django.contrib.auth.decorators import login_required class UserCenterInfoView(View): @method_decorator(login_required) def get(self,request): return render(request,'centerinfo.html')
注:上面是個個人中心的視圖函數,因為需要用到裝飾器,所有我這里需要用到類裝飾器的方法,在稍后我會講解類裝飾器的用法
login_required 這個方法 接收兩個參數,
1,login_url='/login/' 這個參數表示用戶被重定向登錄頁面 當然也可以不進行制定 ,我們在settings中定義
#如果后台login_required 裝飾器未指定跳轉路徑,這里需要定義下 LOGIN_URL = '/login/'
2,redirect_field_name='next' 這個方法值默認是next,它代表登錄成功后需要跳轉的頁面,當然我們可以重寫覆蓋next
下面登錄函數實現后台控制用戶登錄對頁面訪問的權限
class LoginView(View): ''' 登錄 ''' def get(self,request): return render(request,'login.html') def post(self,request): if request.user.is_authenticated(): return HttpResponse('該用戶已登錄,請勿重復登錄') username = request.POST.get('username') pwd = request.POST.get('pwd') user = authenticate(username=username,password=pwd) if user is not None: if user.is_active: login(request,user) request.session['username'] = user.username next = request.GET.get('next') #主要這里 ,捕獲next 值是否存在 if next is None: return redirect(reverse('demo:index')) else: return redirect(next) else: return render(request,'login.html',{'msg':'用戶名或密碼錯誤'},status=400)
7,引用user模型
不要直接引用User
,而應該使用django.contrib.auth.get_user_model()
引用User
模型。(下面是關聯User表的方法)
from django.conf import settings from django.db import models class UserInfo(models.Model): auther = models.ForeignKey(settings.AUTH_USER_MODEL) #這個參數setting里不需要定義的
view視圖中我們這要調用:
from django.contrib.auth import get_user_model User = get_user_model()
8,重寫user表,增加字段設置
models中:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser): mobile = models.CharField(max_length=11,unique=True,verbose_name='手機號')
並且在setting中進行 設置:
AUTH_USER_MODEL = 'users.User' #應用表 + 表名
這樣就可以給django認證的user表 增加字段
9,django認證保持登錄狀態機制
Django引申出了session.login,就是生成session。對應的django在數據庫中自動生成了django_session表用於存放用戶session。
表字段session_key就是瀏覽器中的session_id,
session_data是對賬號密碼等信息做了加密的,expire_date是過期時間;在setting中可設置過期時間。
這個session_id是怎么做到轉換回賬號密碼等信息的?因為我們在后台是可以直接request.user的。
INSTALLED_APPS = [ 'django.contrib.sessions', ]
這個app是會對我們每次request和respone的請求做攔截的,攔截瀏覽器過來的時候就會在里面找到我們的session_id。
然后來數據表查詢session_data並解密,我們response的時候他也會主動加上session_id。
cookies
session表
10,類裝飾器用法
1,為全部請求方法添加裝飾器
from django.utils.decorators import method_decorator @method_decorator(my_decorator, name='dispatch') class DemoView(View): def get(self, request): print('get方法') return HttpResponse('ok') def post(self, request): print('post方法') return HttpResponse('ok')
2,為特定請求方法添加裝飾器
@method_decorator(my_decorator, name='get') class DemoView(View): def get(self, request): print('get方法') return HttpResponse('ok') def post(self, request): print('post方法') return HttpResponse('ok')
3, 為特定請求方法添加裝飾器
class DemoView(View): @method_decorator(my_decorator) # 為get方法添加了裝飾器 def get(self, request): print('get方法') return HttpResponse('ok') @method_decorator(my_decorator) # 為post方法添加了裝飾器 def post(self, request): print('post方法') return HttpResponse('ok') def put(self, request): # 沒有為put方法添加裝飾器 print('put方法') return HttpResponse('ok')