1. 程式人生 > >Django自帶表User認證詳解

Django自帶表User認證詳解


認證登陸(附方法實現程式碼,百度網盤拉取即可下載,啟用碼: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')

 

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')