無(wú)錫網(wǎng)站優(yōu)化價(jià)格福鼎網(wǎng)站優(yōu)化公司
Cookie簡(jiǎn)介
Cookie,有時(shí)也用Cookies,是指web程序?yàn)榱吮鎰e用戶身份、進(jìn)行 session 跟蹤而儲(chǔ)存在用戶本地終端上的數(shù)據(jù)(通常經(jīng)過(guò)加密),一般是以鍵值對(duì)的形式存在,Cookie具有不可跨域名性
Cookie是http協(xié)議中定義在 header 中的字段
Cookie解決無(wú)狀態(tài)問(wèn)題原理
客戶端訪問(wèn)服務(wù)端,服務(wù)端生成一個(gè)有限時(shí)間的cookie給客戶端,cookie保存在客戶端本地瀏覽器,下次進(jìn)行訪問(wèn)的時(shí)候,客戶端就會(huì)攜帶cookie訪問(wèn)服務(wù)端,服務(wù)端可以通過(guò)cookie辨別客戶端用戶
Cookie的使用
from django.shortcuts import render
from django.http import HttpResponse# Create your views here.# 體驗(yàn)了一下報(bào)錯(cuò):The view createCookie_app.views.cookie_index didn't return an HttpResponse object. It returned None instead.
def cookie_index(request):return HttpResponse("設(shè)置cookie").set_cookie('name', 'root')# 先用這種
def cookie_index1(request):resp = HttpResponse("設(shè)置cookie")resp.set_cookie('name', 'root')return respdef cookie_get(request):print(request.COOKIES)return HttpResponse('獲取cookie:%s' % request.COOKIES['name'])
Cookie的免登錄設(shè)置
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect# Create your views here.
from django.urls import reversedef login(request):return render(request, 'login/login.html')def do_login(request):resp = HttpResponse()# 獲取請(qǐng)求體數(shù)據(jù)data = request.POSTusername = data['uname']password = data['pwd']try:rember = data['rember']except:rember = '0'print('username:', username)print('password:', password)if username == 'django' and password == '123':resp.content = '登錄成功'if rember == 'rember':print('設(shè)置cookie')# 設(shè)置cookieresp.set_cookie('uname', username, max_age=60*60*24*3)resp.set_cookie('pwd', password, max_age=60*60*24*3)else:# 刪除cookieresp.delete_cookie('uname')resp.delete_cookie('pwd')return respelse:return HttpResponseRedirect(reverse('login'), {'msg': '用戶名或密碼錯(cuò)誤'})
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h1>登錄頁(yè)面</h1>{% csrf_token %}<form action="/do_login/" method="post">{% csrf_token %}用戶名:<input type="text" name="uname" ><br>密碼:<input type="password" name="pwd" ><br>記住我<input type="checkbox" name="rember" value="rember"><br><input type="submit" value="登錄"><br></form>
</body>
</html>
from django.urls import path
from .views import *urlpatterns = [path('login/', login, name='login'),path('do_login/', do_login, name='logout')
]
Session介紹
Session 對(duì)象存儲(chǔ)特定用戶會(huì)話所需的屬性及配置信息。當(dāng)用戶在應(yīng)用程序的 Web 頁(yè)之間跳轉(zhuǎn)時(shí),存儲(chǔ)在 Session 對(duì)象中的變量將不會(huì)丟失,而且在整個(gè)用戶會(huì)話中一直存在下去。(session是依賴于cookie的)
Django框架中的session管理允許存儲(chǔ)和檢索任意數(shù)據(jù),它在服務(wù)器端存儲(chǔ)數(shù)據(jù)并抽象cookie的發(fā)送和接收。
啟用session
要應(yīng)用session,必須開(kāi)啟session中間層,在settings.py中:
MIDDLEWARE = [# 啟用 Session 中間層'django.contrib.sessions.middleware.SessionMiddleware',
]
五種session的引擎
Django中默認(rèn)支持Session,其內(nèi)部提供了5種類型供開(kāi)發(fā)者使用:
- 數(shù)據(jù)庫(kù)
- 緩存
- 緩存+數(shù)據(jù)庫(kù)
- 文件
- Cookie
五種方式的啟動(dòng)配置各異,但是啟動(dòng)完成后,在程序中的使用方式都相同:
數(shù)據(jù)庫(kù)方式
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
# 數(shù)據(jù)庫(kù)類型的session引擎需要開(kāi)啟此應(yīng)用,啟用 sessions 應(yīng)用
INSTALLED_APPS = ['django.contrib.sessions',
]
緩存
速度最快,但是由于數(shù)據(jù)是保存在內(nèi)存中,所以不是持久性的,服務(wù)器重啟或者內(nèi)存滿了就會(huì)丟失數(shù)據(jù)
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
緩存+數(shù)據(jù)庫(kù)
速度次于單純緩存方式,但是實(shí)現(xiàn)了持久性,每次寫入高速緩存也將寫入數(shù)據(jù)庫(kù),并且如果數(shù)據(jù)尚未存在于緩存中,則使用數(shù)據(jù)庫(kù)
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
一般用以上三種,另外兩種少用,cookie不推薦使用
文件
SESSION_ENGINE = 'django.contrib.sessions.backends.file'
# 設(shè)置文件位置, 默認(rèn)是 tempfile.gettempdir(),
# linux下是:/tmp
# windows下是: C:\Users\51508\AppData\Local\Temp
SESSION_FILE_PATH = 'd:\session_dir'
加密cookie
基于cookie的session,所有數(shù)據(jù)都保存在cookie中,一般情況下不建議使用這種方式
- cookie有長(zhǎng)度限制,4096個(gè)字節(jié)
- cookie不會(huì)因?yàn)榉?wù)端的注銷而無(wú)效,那么可能造成攻擊者使用已經(jīng)登出的cookie模仿用戶繼續(xù)訪問(wèn)網(wǎng)站
- SECRET_KEY這個(gè)配置項(xiàng)絕對(duì)不能泄露,否則會(huì)讓攻擊者可以遠(yuǎn)程執(zhí)行任意代碼
- cookie過(guò)大,會(huì)影響用戶訪問(wèn)速度
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
?Session的設(shè)置
django默認(rèn)就會(huì)配置數(shù)據(jù)庫(kù)存儲(chǔ)session的設(shè)置,所以使用默認(rèn)設(shè)置的時(shí)候需要配置好數(shù)據(jù)庫(kù)信息
進(jìn)行數(shù)據(jù)庫(kù)的同步。數(shù)據(jù)庫(kù)同步后會(huì)發(fā)現(xiàn)數(shù)據(jù)庫(kù)中有一個(gè)django-session的表
之后進(jìn)行設(shè)置的session將會(huì)存儲(chǔ)在這張表內(nèi)
創(chuàng)建與獲取session
session = request.session# 配置session的時(shí)間
session.set_expiry(秒)# 設(shè)置session
session['uname'] = 'xxx'# 獲取sessionuname = session.get('uname')
刪除session
# 刪除某個(gè)key
del request.session['has_commented']
# 從會(huì)話中刪除當(dāng)前會(huì)話數(shù)據(jù)并刪除會(huì)話cookie
flush()
# 設(shè)置會(huì)話的到期時(shí)間
# 如果value是整數(shù),則session將在多少秒不活動(dòng)后到期
# 如果value是一個(gè)datetime或timedelta,該session將在相應(yīng)的日期/時(shí)間到期
# 如果value是0,用戶的會(huì)話cookie將在用戶的Web瀏覽器關(guān)閉時(shí)到期
# 如果value是None,則會(huì)話將恢復(fù)為使用全局會(huì)話到期策略
set_expiry(value)
其他session方法# 設(shè)置測(cè)試cookie以確定用戶的瀏覽器是否支持cookie
set_test_cookie()
# 返回True或者False,取決于用戶的瀏覽器是否接受測(cè)試cookie
test_cookie_worked()
# 刪除測(cè)試cookie
delete_test_cookie()
# 返回此會(huì)話到期之前的秒數(shù)
# kwargs 為 `modification` 和 `expiry`,一般不指定
# modification:最后一次訪問(wèn)日期,默認(rèn)當(dāng)前時(shí)間, now
# expiry: 到期剩余秒數(shù),默認(rèn)全局配置時(shí)間
get_expiry_age(**kwargs)
# 返回此會(huì)話將過(guò)期的日期
# 參數(shù)同 get_expiry_age
get_expiry_date(**kwargs)
# 返回True或者False,取決于用戶的Web瀏覽器關(guān)閉時(shí)用戶的會(huì)話cookie是否會(huì)過(guò)期
get_expire_at_browser_close()
# 從會(huì)話存儲(chǔ)中刪除過(guò)期的會(huì)話,這是個(gè)類方法。
clear_expired()
# 在保留當(dāng)前會(huì)話數(shù)據(jù)的同時(shí)創(chuàng)建新的會(huì)話密鑰
cycle_key()
?session的settings.py使用
# Session的cookie保存在瀏覽器上時(shí)的key,即:sessionid=隨機(jī)字符串(默認(rèn))
SESSION_COOKIE_NAME = "sessionid"?
# Session的cookie保存的路徑(默認(rèn))
SESSION_COOKIE_PATH = "/"?
# Session的cookie保存的域名(默認(rèn))
SESSION_COOKIE_DOMAIN = None
# 是否Https傳輸cookie(默認(rèn))
SESSION_COOKIE_SECURE = False
# 是否Session的cookie只支持http傳輸(默認(rèn))
SESSION_COOKIE_HTTPONLY = True
# Session的cookie失效日期(2周)(默認(rèn))
SESSION_COOKIE_AGE = 1209600
# 是否關(guān)閉瀏覽器使得Session過(guò)期(默認(rèn))
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
# 是否每次請(qǐng)求都保存Session,默認(rèn)修改之后才保存(默認(rèn))
SESSION_SAVE_EVERY_REQUEST = False ?
session登錄
使用了admin的后臺(tái)管理系統(tǒng)
-
用django后臺(tái)管理的用戶登錄驗(yàn)證
-
實(shí)現(xiàn)登錄功能
-
django.contrib.auth
- authenticate():?https://docs.djangoproject.com/zh-hans/4.1/topics/auth/default/#authenticating-users
- login():?使用 Django 的驗(yàn)證系統(tǒng) | Django 文檔 | Django
-
-
實(shí)現(xiàn)退出用戶功能
- logout():?使用 Django 的驗(yàn)證系統(tǒng) | Django 文檔 | Django
-
沒(méi)登錄自動(dòng)跳登錄頁(yè)面
django.contrib.auth.decorators.login_required
實(shí)現(xiàn)- login_required() :使用 Django 的驗(yàn)證系統(tǒng) | Django 文檔 | Django
views.py
重定向還有模板jinja2語(yǔ)法好重要喲
from django.contrib import auth
from django.contrib.auth import authenticate, login
from django.shortcuts import render, redirect
from django.views import View
from django.urls import reverse
from django.http import HttpResponseRedirect
# Create your views here.class m_login(View):def get(self, request):error_message = request.session.get('login_err')request.session['login_err'] = Nonereturn render(request, 'login.html', {'login_err':error_message})def post(self, request):username = request.POST.get('uname')password = request.POST.get('pwd')print(username)print(password)user = auth.authenticate(username=username, password=password)if user:login(request, user) # login() 會(huì)在 session 中保存用戶的ID。return render(request, 'index.html', {'name': username})# return render(request, 'index.html', {'name': username})else:request.session['login_err'] = '用戶名或密碼錯(cuò)誤!'return redirect('session:login')def index(request):# 判斷用戶是否登錄# 沒(méi)有登錄return HttpResponseRedirect(reverse('session:login'))
session登出
# 判斷用戶是否登錄,# 沒(méi)有登錄,則跳轉(zhuǎn)到登錄頁(yè)面
@login_required(login_url='session:login')
def index(request):# 有登錄正常返回首頁(yè)return HttpResponseRedirect(reverse('session:index'))# 退出登錄
def logout(request):auth.logout(request) # 清除session中的用戶信息return HttpResponseRedirect(reverse('session:login'))