Django的用戶認證組件

1、使用用戶認證組件的前提

  功能:用session記錄登陸驗證狀態。html

  用戶表:使用Django自帶的auth_user表,即用戶認證組件表。python

  建立超級用戶:python3 manage.py createsuperuser算法

  建立普通用戶:python3 manage.py createuser數據庫

一、重點API

from django.contrib import auth:
    一、if 驗證成功返回user對象,不然返回None
         user = auth.authenticate(username=user, password = pwd)
    二、auth.login(request, user)      # request.user當前登陸對象
    三、auth.logout(request)
         from django.contrib。auth.models import User  # User == auth_user
    四、request.user.is_authenticated()
    五、user = User.objects.create_user(username='', password='',email='')

二、匿名用戶對象

"""
匿名用戶
    class models.AnonymousUser
    django.contrib.auth.models.AnonymousUser 類實現了django.contrib.auth.models.User 接口,但具備下面幾個不一樣點:
 
    id 永遠爲None。
    username 永遠爲空字符串。
    get_username() 永遠返回空字符串。
    is_staff 和 is_superuser 永遠爲False。
    is_active 永遠爲 False。
    groups 和 user_permissions 永遠爲空。
    is_anonymous() 返回True 而不是False。
    is_authenticated() 返回False 而不是True。
    set_password()、check_password()、save() 和delete() 引起 NotImplementedError。
    New in Django 1.8:
    新增 AnonymousUser.get_username() 以更好地模擬 django.contrib.auth.models.User。
"""

2、auth模塊

# 在視圖中引入auth模塊
from django.contrib import auth

一、authenticate()

  authenticate()方法提供了用戶認證,即驗證用戶名以及密碼是否正確,通常須要username  password兩個關鍵字參數。django

  若是認證信息有效,會返回一個  User  對象;若是認證失敗,則返回None。authenticate()會在User 對象上設置一個屬性標識那種認證後端認證了該用戶,且該信息在後面的登陸過程當中是須要的。當咱們試圖登錄一個從數據庫中直接取出來不通過authenticate()的User對象會報錯的!!後端

from django.shortcuts import render
# Create your views here.
from django.contrib import auth

def login(request):
    if request.method == "POST":
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")
        # 若是驗證成功返回user對象,不然返回None
        user = auth.authenticate(username=user,password=pwd)

    return render(request, "login.html")

二、login(HttpRequest, user)

  login函數的參數:該函數接受一個HttpRequest對象,以及一個認證了的User對象session

  此函數使用django的session框架給某個已認證的用戶附加上session id等信息。框架

from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
from django.contrib import auth

def login(request):
    if request.method == "POST":
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")
        # 若是驗證成功返回user對象,不然返回None
        user = auth.authenticate(username=user, password=pwd)
        if user:
            auth.login(request, user)   # request.user:當前登陸對象
            return redirect("/index/")
    return render(request, "login.html")

  request.user是全局變量,在任何視圖和模板中能夠直接使用(這也是這套用戶認證最大的優勢)。函數

  在沒有經過登陸驗證的狀況下爲匿名用戶。所以能夠根據匿名用戶特色判斷是否登陸驗證經過,同時也能夠直接經過{{request.user.username}}在模板中顯示用戶名。ui

  但在通過auth.login(request, user) 後爲登陸對象

def index(request):
    print("request.user", request.user)  # AnonymousUser  匿名用戶
    # 沒有登陸驗證過即匿名用戶
    print("request.user", request.user.username)  # 返回空字符串
    print("request.user", request.user.id)  # 返回None
    print("request.user", request.user.is_anonymous)   # 返回 True

    # request.user是全局變量
    if request.user.is_anonymous:
        return redirect("/login/")

    # 給模板中傳入username
    # username = request.user.username
    # return render(request, "index.html", {"username": username})   # 模板中經過{{ username }}取到用戶名
    # 改寫爲:
    return render(request, "index.html")  # 模板中經過{{ request.user.username }}就能夠取到用戶名

三、logout(request)註銷用戶

def logout(request):
    auth.logout(request)   # 主要就是作了一個request.session.flush()

    return redirect("/login/")

  該函數接受一個HttpRequest對象,無返回值。當調用該函數時,當前請求的session信息會所有清除。該用戶即便沒有登陸,使用該函數也不會報錯。

3、User對象

  User 對象屬性:username, password(必填項)password用哈希算法保存到數據庫 。

一、user對象的 is_authenticated()

  user.is_authenticated:若是是真正的 User 對象,返回值恆爲 True 。 用於檢查用戶是否已經經過了認證。

  經過認證並不意味着用戶擁有任何權限,甚至也不檢查該用戶是否處於激活狀態,這只是代表用戶成功的經過了認證。 這個方法很重要, 在後臺用request.user.is_authenticated判斷用戶是否已經登陸,若是true則能夠向前臺展現request.user.name。

要求:

  1  用戶登錄後才能訪問某些頁面,

  2  若是用戶沒有登陸就訪問該頁面的話直接跳到登陸頁面

  3  用戶在跳轉的登錄界面中完成登錄後,自動訪問跳轉到以前訪問的地址

方法1:

def index(request):
    # if request.user.is_anonymous:
    # 改寫爲:
    if not request.user.is_authenticated:
        return redirect("/login/")
    return render(request, "index.html")  # 模板中經過{{ request.user.username }}就能夠取到用戶名  

方法2:

  django設計的一個專門用於這種狀況的裝飾器:login_required()

from django.contrib.auth.decorators import login_required
      
@login_required
def index(request):
    return render(request, "index.html") 

@login_required
def order(request):
    return render(request, "order.html")

  若用戶沒有登陸,則會跳轉到django默認的登陸URL '/accounts/login/ ' (這個值能夠在settings文件中經過LOGIN_URL進行修改)。

STATIC_URL = '/static/'

LOGIN_URL = "/login/"   # 不配這個訪問index會跳轉到,http://127.0.0.1:8000/accounts/login/?next=/index/

  修改後,用戶訪問.../order/和.../index/頁面時,會跳轉到login頁面,同時會傳遞當前訪問url的絕對路徑(登陸成功後,會重定向到該路徑)。  

  代碼示例總體以下:

from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
from django.contrib import auth
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required

def login(request):
    if request.method == "POST":
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")
        # 若是驗證成功返回user對象,不然返回None
        user = auth.authenticate(username=user, password=pwd)
        if user:
            auth.login(request, user)   # request.user:當前登陸對象
            next_url = request.GET.get("next", "/index/")  # 登陸成功跳轉的url,若是取不到跳轉首頁
            return redirect(next_url)
    return render(request, "login.html")

@login_required
def index(request):
    return render(request, "index.html")  # 模板中經過{{ request.user.username }}就能夠取到用戶名

def logout(request):
    auth.logout(request)   # 主要就是作了一個request.session.flush()
    return redirect("/login/")

def reg(request):
    if request.method == "POST":
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")
        # 使用create_user輔助函數建立用戶
        user = User.objects.create_user(username=user, password=pwd)

        # 註冊成功跳轉到登陸頁面
        return redirect("/login/")
    return render(request, "reg.html")

@login_required
def order(request):
    return render(request, "order.html")

二、建立用戶

  使用 create_user 輔助函數建立用戶:

from django.contrib.auth.models import User

def reg(request):
    if request.method == "POST":
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")
        # 不能用下面這個方法插入:
        # User.objects.create(username=user, password=pwd)
        # 使用create_user輔助函數建立用戶
        user = User.objects.create_user(username=user, password=pwd)
        # 註冊成功跳轉到登陸頁面
        return redirect("/login")
    return render(request, "reg.html")

三、check_password(passwd)

  用戶須要修改密碼的時候 首先要讓他輸入原來的密碼 ,若是給定的字符串經過了密碼檢查,返回 True.

 

四、修改密碼

  使用 set_password() 來修改密碼:

user = User.objects.get(username='')
user.set_password(password='')
user.save 

五、簡單示例

(1)註冊:

def sign_up(request):
 
    state = None
    if request.method == 'POST':
 
        password = request.POST.get('password', '')
        repeat_password = request.POST.get('repeat_password', '')
        email=request.POST.get('email', '')
        username = request.POST.get('username', '')
        if User.objects.filter(username=username):
                state = 'user_exist'
        else:
                new_user = User.objects.create_user(username=username, password=password,email=email)
                new_user.save()
 
                return redirect('/book/')
    content = {
        'state': state,
        'user': None,
    }
    return render(request, 'sign_up.html', content)  

(2)修改密碼:

@login_required
def set_password(request):
    user = request.user
    state = None
    if request.method == 'POST':
        old_password = request.POST.get('old_password', '')
        new_password = request.POST.get('new_password', '')
        repeat_password = request.POST.get('repeat_password', '')
        if user.check_password(old_password):
            if not new_password:
                state = 'empty'
            elif new_password != repeat_password:
                state = 'repeat_error'
            else:
                user.set_password(new_password)
                user.save()
                return redirect("/log_in/")
        else:
            state = 'password_error'
    content = {
        'user': user,
        'state': state,
    }
    return render(request, 'set_password.html', content)
相關文章
相關標籤/搜索