Django實現cookie&session以及認證系統
COOKIE&SESSION
知識儲備
由於http協議無法保持狀態,但實際情況,我們卻又需要“保持狀態”,因此cookie就是在這樣一個場景下誕生。
cookie的工作原理是:由服務器產生內容,瀏覽器收到請求後保存在本地;當瀏覽器再次訪問時,瀏覽器會自動帶上cookie,這樣服務器就能通過cookie的內容來判斷這個是“誰”了。
cookie雖然在一定程度上解決了“保持狀態”的需求,但是由於cookie本身最大支持4096字節,以及cookie本身保存在客戶端,可能被攔截或竊取,因此就需要有一種新的東西,它能支持更多的字節,並且他保存在服務器,有較高的安全性。這就是session。
問題來了,基於http協議的無狀態特征,服務器根本就不知道訪問者是“誰”。那麽上述的cookie就起到橋接的作用。
我們可以給每個客戶端的cookie分配一個唯一的id,這樣用戶在訪問時,通過cookie,服務器就知道來的人是“誰”。然後我們再根據不同的cookie的id,在服務器上保存一段時間的私密資料,如“賬號密碼”等等。
總結而言:cookie彌補了http無狀態的不足,讓服務器知道來的人是“誰”;但是cookie以文本的形式保存在本地,自身安全性較差;所以我們就通過cookie識別不同的用戶,對應的在session裏保存私密的信息以及超過4096字節的文本
Django實現COOKIE
設置cookie
obj = HttpResponse(...) 或 obj= render(request, ...) 或 obj= redirect()
obj.set_cookie(key,value,...)
obj.set_signed_cookie(key,value,salt=
‘加密鹽‘
,...)
獲取cookie
request.COOKIES.get(‘key‘)
request.get_signed_cookie(key, default=
RAISE_ERROR, salt
=
‘‘, max_age
=
None
)
刪除cookie
response.delete_cookie("cookie_key",path="/",domain=name)
參數
key, 鍵 value=‘‘, 值 max_age=None, 超長時間 expires=None, 超長時間 path=‘/‘, Cookie生效的路徑,瀏覽器只會把cookie回傳給帶有該路徑的頁面,這樣可以避免將cookie傳給站點中的其他的應用。/ 表示根路徑,特殊的:根路徑的cookie可以被任何url的頁面訪問 domain=None, Cookie生效的域名你可用這個參數來構造一個跨站cookie。如, domain=".example.com"所構造的cookie對下面這些站點都是可讀www.example.com 、 www2.example.com 和an.other.sub.domain.example.com 。 如果該參數設置為 None ,cookie只能由設置它的站點讀取。 secure=False, 如果設置為 True ,瀏覽器將通過HTTPS來回傳cookie。 httponly=False 只能http協議傳輸,無法被JavaScript獲取 (不是絕對,底層抓包可以獲取到也可以被覆蓋
$.cookie("key", value,{ path: ‘/‘ })jquery操作cookie
Django實現SESSION
設置Session
request.session[‘key‘]=‘value‘ ‘‘‘ 實際進行的操作: 1. 檢查請求是否有sessionid,且是否存在與數據庫,存在則對session_data進行更新 2. 若不等,則創建隨機字符串 3. set_cookie(‘sessionid‘,‘隨機字符串‘) 4. 在session表中添加記錄 session-key session-data 隨機字符串 {"key":"value"}-------------進行處理後的 ‘‘‘
獲取Session
session_name=request.session[‘key‘] ‘‘‘ 實際進行了哪些操作: 1. 取隨機字符串request.COOKIE.get(‘sessionid‘) 2. 在session表中進行過濾: obj=django-session.objects.filter(session-key=random_str).first() obj.session-data.get("user") ‘‘‘
其他
#刪除Sessions值 del request.session["session_name"] #檢測是否操作session值 if "session_name" is request.session:
配置
Django默認支持Session,並且默認是將Session數據存儲在數據庫中,即:django_session 表中。 a. 配置 settings.py SESSION_ENGINE = ‘django.contrib.sessions.backends.db‘ # 引擎(默認) SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串(默認) SESSION_COOKIE_PATH = "/" # Session的cookie保存的路徑(默認) SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默認) SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie(默認) SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http傳輸(默認) SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默認) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉瀏覽器使得Session過期(默認) SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都保存Session,默認修改之後才保存(默認數據庫配置(配置)
a. 配置 settings.py SESSION_ENGINE = ‘django.contrib.sessions.backends.cache‘ # 引擎 SESSION_CACHE_ALIAS = ‘default‘ # 使用的緩存別名(默認內存緩存,也可以是memcache),此處別名依賴緩存的設置 SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路徑 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名 SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http傳輸 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉瀏覽器使得Session過期 SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都保存Session,默認修改之後才保存緩存配置
a. 配置 settings.py SESSION_ENGINE = ‘django.contrib.sessions.backends.file‘ # 引擎 SESSION_FILE_PATH = None # 緩存文件路徑,如果為None,則使用tempfile模塊獲取一個臨時地址tempfile.gettempdir() SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路徑 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名 SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http傳輸 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉瀏覽器使得Session過期 SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都保存Session,默認修改之後才保存文件配置
def login_session(request): if request.method==‘POST‘: user=request.POST.get(‘user‘) pwd=request.POST.get(‘pwd‘) ret=UserInfo.objects.filter(name=user,pwd=pwd) if ret: request.session[‘user‘]=user return redirect(‘/index_session/‘) return render(request,‘login.html‘) def index_session(request): user=request.session.get(‘user‘) if not user: return redirect(‘/login_session/‘) return render(request,‘index.html‘,locals())View Code
Django的用戶認證
auth
利用auth模塊中的一些方法來進行認證 from django.contrib import auth
authenticate()
提供了用戶認證,即驗證用戶名以及密碼是否正確,一般需要username password兩個關鍵字參數
如果認證信息有效,會返回一個 User 對象。authenticate()會在User 對象上設置一個屬性標識那種認證後端認證了該用戶,且該信息在後面的登錄過程中是需要的。當我們試圖登陸一個從數據庫中直接取出來不經過authenticate()的User對象會報錯的
user = authenticate(username=‘someone‘,password=‘somepassword‘)
login(HttpRequest, user)
該函數接受一個HttpRequest對象,以及一個認證了的User對象
此函數使用django的session框架給某個已認證的用戶附加上session id等信息。
login(request, user)
logout(request)
該函數接受一個HttpRequest對象,無返回值。當調用該函數時,當前請求的session信息會全部清除。該用戶即使沒有登錄,使用該函數也不會報錯。
logout(request)
User對象
User 對象屬性:
username, password(必填項)password用哈希算法保存到數據庫
is_staff : 用戶是否擁有網站的管理權限.
is_active : 是否允許用戶登錄, 設置為``False``,可以不用刪除用戶來禁止 用戶登錄
is_authenticated()
如果是真正的 User 對象,返回值恒為 True 。 用於檢查用戶是否已經通過了認證。
通過認證並不意味著用戶擁有任何權限,甚至也不檢查該用戶是否處於激活狀態,這只是表明用戶成功的通過了認證。 這個方法很重要, 在後臺用request.user.is_authenticated()判斷用戶是否已經登錄,如果true則可以向前臺展示request.user.name
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文件中通過LOGIN_URL進行修改)。並傳遞 當前訪問url的絕對路徑 (登陸成功後,會重定向到該路徑)。
創建用戶
from django.contrib.auth.models import User user = User.objects.create_user(username=‘‘,password=‘‘,email=‘‘)
修改密碼set_password()
user = User.objects.get(username=‘‘) user.set_password(password=‘‘) user.save
check_password(passwd)
用戶需要修改密碼的時候 首先要讓他輸入原來的密碼 ,如果給定的字符串通過了密碼檢查,返回 True
基於auth認證實現登錄:
def login(request): ‘‘‘ 登錄驗證 :param request: :return: ‘‘‘ if request.method==‘POST‘: username=request.POST.get(‘username‘) pwd=request.POST.get(‘pwd‘) input_valid_code=request.POST.get(‘valid_code‘) valid_code=request.session.get(‘valid_code‘) login_response={‘user‘:None,‘error_msg‘:‘‘} #進行驗證碼的比較 if valid_code.upper()==input_valid_code.upper(): user=auth.authenticate(username=username,password=pwd) if user: auth.login(request,user) login_response[‘user‘]=user.username else: login_response[‘error_msg‘]=‘用戶名或密碼錯誤!‘ else: login_response[‘error_msg‘]=‘驗證碼錯誤!‘ import json return HttpResponse(json.dumps(login_response)) return render(request,‘login.html‘,locals())
Django實現cookie&session以及認證系統