前提: 用戶認證組件: 功能:用session記錄登陸驗證狀態 前提:用戶表:django自帶的auth_user表 建立超極用戶:Python3 manage.py createsuperuser API: from django.contrib import auth: 1 # 若是 驗證成功返回user對象,不然返回None user = auth.authenticate(username=user, password=pwd) 2 auth.login(request, user) # session註冊login, request.user:當前登陸對象,若沒有就是個匿名對象(全局對象) 3 auth.logout(request) # 註銷 from django.contrib.auth.models import User # User==auth_user 4 request.user.is_authenticated: # 是否經過校驗 5 user = User.objects.create_user(username='',password='',email='') # 註冊用戶 補充: 匿名用戶對象: 總結: if not: auth.login(request,user) request.user == AnonymousUser() else:reuqest.user==登陸對象 reuqest.user是一個全局變量,能夠在任何視圖和模板直接使用 以前咱們本身建立session獲得django_session表中,一個瀏覽器登陸兩個用戶的時候他們的session_key不變,第二個用戶省下的內容會進行更新 可是,當咱們引入用戶認證組件的時候,一個瀏覽器登陸兩個用戶的時候,全部的內容都會改變,以下,登陸mumu和mm兩個用戶在django_session表中數據:(第二條數據會覆蓋第一條數據) session_key session_data expire_date hdnc2g9a6fuqf7svei9lb28vage8f0vz N2Q1MjQ5MTBmMjMzZmVmYmJlMWE5YmE0NDA2ZTM4NGFkNWM1MWIzNzp7Il9hdXRoX3VzZXJfYmFja2VuZCI6ImRqYW5nby5jb250cmliLmF1dGguYmFja2VuZHMuTW9kZWxCYWNrZW5kIiwiX2F1dGhfdXNlcl9pZCI6IjEiLCJfYXV0aF91c2VyX2hhc2giOiJjM2Q4YmVmZmY0OTk0NDQwZmUxN2MyNzQ3MTkxMzljNjRhM2FmMWMwIn0 2019-03-01 08:21:08.066179 hrzi7dm7nmskrn3m1usofdg5edn6ar76 ZTczOTlkMzM2M2EyNmExZTZhYzU3YjlhZWQ3ZDU0MDY4N2Q1ZjAyNTp7Il9hdXRoX3VzZXJfaGFzaCI6ImY3NTc2ZmExNjYwNmU4YmQwZmZkMzRiYjdmYWNlZGY5ZTVlOTAzZjciLCJfYXV0aF91c2VyX2JhY2tlbmQiOiJkamFuZ28uY29udHJpYi5hdXRoLmJhY2tlbmRzLk1vZGVsQmFja2VuZCIsIl9hdXRoX3VzZXJfaWQiOiIyIn0 2019-03-01 08:36:15.915105 ############################################ F:\Python全棧開發_中級\第六模塊\Web開發\authDemo>python manage.py makemigrations No changes detected 問題解決方法: 先 python manage.py makemigrations --empty yourappname 生成一個空的initial.py 再 python manage.py makemigrations 生成原先的model對應的migration file
from django.contrib import auth django.contrib.auth中提供了許多方法,這裏主要介紹其中的三個: authenticate() 提供了用戶認證,即驗證用戶名以及密碼是否正確,通常須要username password兩個關鍵字參數 若是認證信息有效,會返回一個 User 對象。authenticate()會在User 對象上設置一個屬性來標識後端已經認證了該用戶,且該信息在後續的登陸過程當中是須要的。 當咱們試圖登錄一個從數據庫中直接取出來不通過authenticate()的User對象時會報錯!!! user = authenticate(username='theuser',password='thepassword') login(HttpRequest, user) 該函數接受一個HttpRequest對象,以及一個認證了的User對象 此函數使用django的session框架給某個已認證的用戶附加上session id等信息。 複製代碼 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: login(request, user) # Redirect to a success page. ... else: # Return an 'invalid login' error message. ... 複製代碼 logout(request) 註銷用戶 from django.contrib.auth import logout def logout_view(request): logout(request) # Redirect to a success page. 該函數接受一個HttpRequest對象,無返回值。當調用該函數時,當前請求的session信息會所有清除。該用戶即便沒有登陸,使用該函數也不會報錯
User 對象屬性:username, password(必填項)password用哈希算法保存到數據庫 is_staff : 用戶是否擁有網站的管理權限. is_active : 是否容許用戶登陸, 設置爲``False``,能夠不用刪除用戶來禁止 用戶登陸 user對象的 is_authenticated() 若是是真正的 User 對象,返回值恆爲 True 。 用於檢查用戶是否已經經過了認證。 經過認證並不意味着用戶擁有任何權限,甚至也不檢查該用戶是否處於激活狀態,這只是代表用戶成功的經過了認證。 這個方法很重要, 在後臺用request.user.is_authenticated()判斷用戶是否已經登陸,若是true則能夠向前臺展現request.user.name 要求: 1 用戶登錄後才能訪問某些頁面, 2 若是用戶沒有登陸就訪問該頁面的話直接跳到登陸頁面 3 用戶在跳轉的登錄界面中完成登錄後,自動訪問跳轉到以前訪問的地址 方法一: def my_view(request): if not request.user.is_authenticated(): return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path)) 方法二: django已經爲咱們設計好了一個用於此種狀況的裝飾器:login_requierd() from django.contrib.auth.decorators import login_required @login_required def my_view(request): ... 若用戶沒有登陸,則會跳轉到django默認的 登陸URL '/accounts/login/ ' (這個值能夠在settings.py文件中經過LOGIN_URL進行修改)。並傳遞 當前訪問url的絕對路徑 (登錄成功後,會重定向到該路徑)。 建立用戶 使用 create_user 輔助函數建立用戶: from django.contrib.auth.models import User user = User.objects.create_user(username='',password='',email='') check_password(passwd) 用戶須要修改密碼的時候,首先要讓其輸入原來的密碼 ,若是給定的值經過了密碼檢查,返回 True 修改密碼 使用 set_password() 來修改密碼 user = User.objects.get(username='') user.set_password(password='') user.save() http://www.cnblogs.com/yuanchenqi/articles/9064397.html https://www.cnblogs.com/liwenzhou/p/9030211.html
用戶認證組件:邏輯更完善!!嚴謹 本身寫得 存 session字段必需要都一致,然而有一些超級用戶和普通用戶應該不同!! http://www.cnblogs.com/yuanchenqi/articles/9064397.html 前提: 用戶認證組件前提: 功能:用session記錄登陸驗證狀態 前提:用戶表:django auth-user # 用戶認證組件表 擴展 auth-user one2one 或繼承 建立超級用戶: python3 manage.py createsuperuser API: from django.contrib import auth from django.contrib.auth.models import User # User == auth_user 1.auth.authenticate() 2.auth.login() # request.user 當前用戶對象 是 auth-user表對象 全局可隨便用 3.auth.logout() 4.request.user.is_authenticated 5.User.objects.create_user() 6.user.set_password() 補充: 匿名用戶對象: 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。 總結: if not auth.login(request,user) request.user == AnonymouseUser() else: request.user == 登陸對象 request.user 是一個全局變量 在任何視圖和模板直接使用!! 示例: from django.contrib import auth # 驗證成功返回user對象,不然返回None def login(request): user = request.POST.get('name') pwd = request.POST.get('pwd') user = auth.authenticate(username=user,password=pwd) if user: auth.login(request,user) # request.user = 當前登陸對象 , 沒有登陸 取出來得是匿名用戶(AnonymousUser) # session表裏的 session-id session-data 一個瀏覽器,不一樣得用戶,兩個字段都會變 # 本身寫得session session-id 不會變 不一樣用戶,同一瀏覽器,只會變session-data return redirect('/index/') return render(request,'login.html') def index(request): print(request.user) print(request.user.username) print(request.user.id) print(request.user.is_anonymouse) # if request.user.is_anonymous: if not request.user.is_authenticated: return redirect('/login/') return render(request,'index.html') <h3>hi,{{ request.user.username }}</h3> def logout(request): auth.logout(request) return redirect('/login/') 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 ) # 不能用這個 pwd 是明文 user = User.objects.create_user(username = user, password = pwd ) return redirect('/login/') return render(request,'reg.html') 修改密碼: user = User.objects.get(username = '') user.set_password(password = '') user.save() 基於用戶認證組件 得 認證裝飾器: ( @login_required ) from django.contrib.auth.decorators import login_required settings: LOGIN_URL = '/login/' # 一會跳轉到哪裏去!! # http://127.0.0.1:8000/login/?next=/index/ def login(request): user = request.POST.get('name') pwd = request.POST.get('pwd') user = auth.authenticate(username=user,password=pwd) if user: auth.login(request,user) next_url = request.GET.get('next','/index/') return redirect(next_url) return render(request,'login.html') @login_required def index(request): return render(request,'index.html')
views.pyhtml
# -*- encoding:utf-8 -*- from django.shortcuts import render, HttpResponse, redirect # Create your views here. from django.contrib import auth # 導入模塊 from django.contrib.auth.models import User # 導入用戶表 def login(request): if request.method == "POST": user = request.POST.get("user") pwd = request.POST.get("pwd") ''' 正常咱們本身建表,下面認證須要引入咱們本身的表進行過濾,可是咱們如今 使用的是django建的表auth_user表,因此要用下面幾步: 1. 導入模塊 from django.contrib import auth 2. 過濾數據 ''' # 若是 驗證成功返回user對象,不然返回None user = auth.authenticate(username=user, password=pwd) if user: auth.login(request, user) # session註冊login, request.user:當前登陸對象,若沒有就是個匿名對象 return redirect("/index/") return render(request, "login.html") def index(request): # print("request.user:", request.user) # print("username:", request.user.username) # print("id:", request.user.id) # print("is_anonymous:", request.user.is_anonymous) ''' 沒有登陸的時候,訪問index頁面的時候,request.user會獲得一個匿名用戶AnonymousUser 上述輸出以下: request.user: AnonymousUser username: id: None is_anonymous: True 登陸以後,訪問index獲得以下輸出: request.user: mumu username: mumu id: 1 is_anonymous: False ''' if request.user.is_anonymous: # 是不是匿名函數 # if not request.user.is_authenticated: # 是否經過校驗 # return redirect("/login/") # username = request.user.username return render(request, "index.html", {"username": username})
login.htmlpython
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>登陸用戶</h3> <form action="" method="post"> {% csrf_token %} 用戶名 <input type="text" name="user"> 密碼 <input type="password" name="pwd"> <input type="submit" value="submit"> </form> </body> </html>
index.html算法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>Hi,{{ username }}!</h3> {# <h3>Hi,{{ request.user.username }}!</h3>#} {# 因爲request.user在整個項目中是個全局變量,因此不須要在視圖中傳入數據映射到模板中 #} </body> </html>
建立用戶:
C:\Users\Administrator\PycharmProjects\authDemo>python manage.py createsuperuser Username (leave blank to use 'administrator'): mm Email address: Password:mm123456 Password (again):mm123456 Superuser created successfully.
建立成功後獲得的auth_user表:數據庫
更新的時候它不像以前那樣子,它把session_key 和session_data數據都更新了,以前都是隻更新session_data,如今邏輯跟嚴謹了。django
views.py後端
def logout(request): # 註銷 auth.logout(request) return redirect("/login/") def reg(request): # 註冊 if request.method == "POST": # 獲取user和pwd方便插入數據庫 user = request.POST.get("user") pwd = request.POST.get("pwd") # User.objects.create(username=user, password=pwd) # 這種方式是不對的,插入的是明文,而實際表中須要的是密文 user = User.objects.create_user(username=user, password=pwd) # 這種方法會轉爲密文 return redirect("/login/") return render(request, "reg.html")
reg.html瀏覽器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>註冊用戶</h3> <form action="" method="post"> {% csrf_token %} 用戶名 <input type="text" name="user"> 密碼 <input type="password" name="pwd"> <input type="submit" value="submit"> </form> </body> </html>
index.htmlsession
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>Hi,{{ username }}!</h3> {# <h3>Hi,{{ request.user.username }}!</h3>#} {# 因爲request.user在整個項目中是個全局變量,因此不須要在視圖中傳入數據映射到模板中 #} <a href="/logout/">註銷</a> </body> </html>
一點擊註銷按鈕,就把django_session裏邊的記錄都給清除了。app
若是是真正的 User 對象,返回值恆爲 True 。 用於檢查用戶是否已經經過了認證。
經過認證並不意味着用戶擁有任何權限,甚至也不檢查該用戶是否處於激活狀態,這只是代表用戶成功的經過了認證。 這個方法很重要, 在後臺用request.user.is_authenticated()判斷用戶是否已經登陸,若是true則能夠向前臺展現request.user.name框架要求:
1 用戶登錄後才能訪問某些頁面,
2 若是用戶沒有登陸就訪問該頁面的話直接跳到登陸頁面
3 用戶在跳轉的登錄界面中完成登錄後,自動訪問跳轉到以前訪問的地址
方法一:
def order(request): print("order") if not request.user.is_authenticated: redirect("/login/") return render(request, "order.html")
方法二:
django已經爲咱們設計好了一個用於此種狀況的裝飾器:login_requierd()
先在settings裏邊設置下我要跳轉到哪一個頁面
STATIC_URL = '/static/' LOGIN_URL = "/login/" #跳轉到哪裏由我本身決定; 不加這個django會給你默認跳轉到 127.0.0.1:8000/accounts/login/?next=/index/;設置好這個後跳轉到:/login/?next=/index/(是訪問index進行跳轉的)
view.py
# -*- encoding:utf-8 -*- 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") ''' 正常咱們本身建表,下面認證須要引入咱們本身的表進行過濾,可是咱們如今 使用的是django建的表auth_user表,因此要用下面幾步: 1. 導入模塊 from django.contrib import auth 2. 過濾數據 ''' # 若是 驗證成功返回user對象,不然返回None user = auth.authenticate(username=user, password=pwd) if user: auth.login(request, user) # session註冊login, request.user:當前登陸對象,若沒有就是個匿名對象 # return redirect("/index/") # 切勿寫死,能夠根據獲取的值來跳轉 next_url = request.GET.get('next', '/index/') # 若是取不到,跳轉到index return redirect(next_url) # 動態的根據參數來配 return render(request, "login.html") @login_required() # 有了裝飾器,就不須要寫下面的認證了 def index(request): # print("request.user:", request.user) # print("username:", request.user.username) # print("id:", request.user.id) # print("is_anonymous:", request.user.is_anonymous) ''' 沒有登陸的時候,訪問index頁面的時候,request.user會獲得一個匿名用戶AnonymousUser 上述輸出以下: request.user: AnonymousUser username: id: None is_anonymous: True 登陸以後,訪問index獲得以下輸出: request.user: mumu username: mumu id: 1 is_anonymous: False ''' # # if request.user.is_anonymous: # 是不是匿名函數 # if not request.user.is_authenticated: # 是否經過校驗 # return redirect("/login/") # username = request.user.username return render(request, "index.html", {"username": username}) def logout(request): auth.logout(request) return redirect("/login/") def reg(request): if request.method == "POST": # 獲取user和pwd方便插入數據庫 user = request.POST.get("user") pwd = request.POST.get("pwd") # User.objects.create(username=user, password=pwd) # 這種方式是不對的,插入的是明文,而實際表中須要的是密文 user = User.objects.create_user(username=user, password=pwd) # 這種方法會轉爲密文 return redirect("/login/") return render(request, "reg.html") @login_required() def order(request): print("order") # if not request.user.is_authenticated: # # redirect("/login/") # 能夠加裝飾器,就不須要這樣寫了 return render(request, "order.html")
若用戶沒有登陸,則會跳轉到django默認的 登陸URL '/accounts/login/ ' (這個值能夠在settings文件中經過LOGIN_URL進行修改)。並傳遞 當前訪問url的絕對路徑 (登錄成功後,會重定向到該路徑)。