PXE無人值守安裝系統
HTTP無狀態
HTTP
具有無狀態的特性,這使得每次使用者的訪問都需要自己輸入使用者名稱及密碼進行登入,像現在諸如淘寶、京東等購物網址根本無法使用。
Cookie技術
為了解決上述問題,產生了Cookie
技術。
Cookie
是服務端儲存至客戶端瀏覽器上的鍵值對。當用戶第一次登入某個網站時,該網站後端伺服器會生成一組key:value
的鍵值對(通常是賬戶
:密碼
),讓客戶端的瀏覽器進行儲存,下次訪問的時候帶上這組鍵值對即可。1.解決了
HTTP
無狀態的特性2.資料極度不安全,由於
key:value
儲存至本地,這使得只要竊取到該資料,就能進行偽造登入
另外,Cookie
1.一個
Cookie
所攜帶的內容大小上限為4KB;2.一個伺服器最多在客戶端瀏覽器上儲存20個
Cookie
; (20個鍵值對)3.一個瀏覽器最多儲存300個
Cookie
;
session技術
由於Cookie
會將賬戶和密碼的鍵值對全部儲存至本地瀏覽器中,這意味著本地的Cookie
一旦遭到竊取,將會面臨很高的風險。
所以在資料安全等各個因素下的考慮,又出現了session
技術。
session
並不會將你的賬戶:密碼
鍵值對交給本地的瀏覽器進行儲存,而是在伺服器上進行儲存(加密儲存)。但是它會返回給本地瀏覽器一組隨機的字串,當客戶端瀏覽器下次訪問時只要帶上這一組隨機字串即可。
1.
session
儲存的方式多種多樣,可以是存放至快取,也可以存放至硬碟2.
session
無法使得同一瀏覽器下同一網站同時登入不同使用者3.
session
可能會大量佔用服務端資源4.
session
基於Cookie
,因為本地要放上隨機字串。
其他技術
為了解決session
將資料存放至服務端造成服務端資源佔用過大的情況,又出現了token
以及jwt
。
這裡簡單瞭解一下token
,關於jwt
後面會單獨記錄。
使用者第一次進行訪問並登入之後,將一段使用者資訊進行加密處理。
把這段加密之後的結果拼接在使用者資訊之後,將整體的這兩段資訊返回給瀏覽器儲存。
使用者第二次訪問時,服務端擷取第一段資訊進行加密,並且與第二段加密資訊做比對,比對成功則代表登入成功。
Django-Cookie
以下是Django
中提供的操縱Cookie
的方法。
方法名稱 | 描述 | 詳細資訊 |
---|---|---|
request.COOKIES.get("cookie") | 獲取Cookie | 無 |
set_cookie("key","value") | 設定Cookie | 參見詳細資訊 |
request.delete_cookie("key") | 刪除Cookie | 參見詳細資訊 |
我該如何獲取Cookie
:
# 如果當前請求的cookie中存在islogin並且有值,那麼就獲取,沒有就用這裡給的預設值None
request.COOKIES.get("islogin",None)
我該如何設定Cookie
:
obj = redirect("/index/")或 HttpResponse(...) 或 render(request, ...)
# 第一種方法(推薦)
obj.set_cookie("islogin",True) # 設定cookie值,注意這裡的引數,一個是鍵,一個是值
obj.set_cookie("lilz","344",20) # 20單位為秒,代表max_age:過期時間
obj.set_cookie("username", username)
# 第二種方法
obj.set_cookie(key,value,...)
# 第三種方法
obj.set_signed_cookie(key,value,salt='加密鹽',...)
這種方法在獲取時,要使用另外的獲取方法
obj.get_signed_cookie(key,salt='加密鹽')
# 引數註解:
max_age:過期時間
path='index'=======>表示訪問index時帶著cookie,其他未設定的不帶cookie
domain:跨域時用
設定Cookie
時的引數詳解:
class HttpResponseBase:
def set_cookie(self, key, 鍵
value='', 值
max_age=None, 超長時間,通常設定這個即可
cookie需要延續的時間(以秒為單位)
如果引數是None ,這個cookie會延續到瀏覽器關閉為止。
expires=None, 超長時間,針對IE瀏覽器
expires預設None ,cookie失效的實際日期/時間。
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
:
obj.delete_cookie("cookie_key",path="/",domain=name) # 只寫key也可以進行刪除
Django-session
以下是Django
中設定session
的一些方法。
以下是注意事項:
1.如果要設定
session
,則必須先執行python manage.py migrate
生成物理表,session
資訊會存放至物理表中。2.在
Django
中,session
預設的超時時間為14天。
1、設定session值
request.session["session_name"]="admin"
request.session.set_expiry(time) 設定超時時間,為秒。如果設定為0則視窗關閉失效,可以是數字,datetime,None,0
2、獲取session值
session_name = request.session.get("session_name")
# 取值時:
(1) request.COOKIE.get("sessionid") 從Cookie中獲取sessionid
(2) 在django-session表中根據sessionid過濾session-key
(3) 一旦對比上了,取出過濾記錄的session-data反序列化資料字典 {"susername":"egon","sis_login":True},然後存入request.session,然後我們就能通過get獲取字典裡的值了
3、刪除session值
del request.session["session_name"] # 刪除一組鍵值對
request.session.flush() # 刪除一條記錄,此操作相當於下面3個步驟
(1) request.COOKIE.get("sessionid) # 取cookie中的值
(2) 在Django-session表過濾session-key的記錄並刪除這條記錄
(3) 刪除cookie,response.delete_cookie("sessionid")
# 為了減輕資料庫的查詢負擔,過一段時間會自動把伺服器的session刪除(14天)
4、檢測是否操作session值
if "session_name" is request.session:
FBV示例
FBV
下,我們可以設定裝飾器,來驗證請求是否帶有Cookie/session
,如果沒有則將先進行登入。
urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index, name="index"),
url(r'^login/', views.login, name="login"),
url(r'^logout/', views.logout, name="logout"),
url(r'^backstage/', views.backstage, name="backstage"),
url(r'^other/', views.other, name="other"),
]
app01/views.py
from django.shortcuts import render
from django.shortcuts import render
from django.shortcuts import redirect
from django.shortcuts import reverse
from django.shortcuts import HttpResponse
# Create your views here.
def wrapp(func):
def inner(request,*args,**kwargs):
if request.session.get("login"):
return func(request,*args,**kwargs)
else:
target_url = request.path_info
return redirect("/login/?next={0}".format(target_url))
return inner
def index(request):
""" 主頁 """
return render(request,"index.html",locals())
def login(request):
""" 登入頁面 """
target_url = request.GET.get("next",None)
if request.method == "POST":
username = request.POST.get("username")
password = request.POST.get("password")
if username == "Yunya" and password == "123456":
request.session["login"] = True
if not target_url:
return redirect("/index/") # 如果是直接點的登入頁面,登陸完成後跳轉到主頁
else:
return redirect(target_url) # 否則跳轉到從其他頁面過來的
return render(request,"login.html",locals())
def logout(request):
""" 登出登入 """
del request.session["login"]
request.session.flush()
return redirect('/index/')
def backstage(request):
""" 後臺頁面 """
return HttpResponse("成功進入後臺頁面")
def other(request):
""" 其他頁面 """
return HttpResponse("成功進入其他頁面")
templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href='https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css' rel='stylesheet'>
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
<script src='https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js'></script>
</head>
<body>
<p><a class="btn btn-primary" href="{% url 'login' %}" role="button">登入</a></p>
<p><a class="btn btn-danger" href="{% url 'logout' %}" role="button">登出</a></p>
<h1>
主頁
</h1>
</body>
</html>
templates/login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="" method="POST">
<p><input type="text" placeholder="username" name="username"></p>
<p><input type="text" placeholder="password" name="password"></p>
<p><button type="submit">登入</button></p>
</form>
</body>
</html>
CBV示例
以下是使用CBV
新增session
認證的方式。
from django.views import View
from django.utils.decorators import method_decorator
def wrapp(func):
def inner(request, *args, **kwargs):
if request.session.get("login"):
return func(request, *args, **kwargs)
else:
target_url = request.path_info
return redirect("/login/?next={0}".format(target_url))
return inner
class Login(View):
def dispatch(self, request, *args, **kwargs):
self.target_url = request.GET.get("next", None)
return super(Login,self).dispatch(request, *args, **kwargs)
def get(self,request):
return render(request, "login.html", locals())
def post(self,request):
username = request.POST.get("username")
password = request.POST.get("password")
if username == "Yunya" and password == "123456": # 這裡的驗證可以新寫一個方法進行
obj = redirect("/index/")
request.session["login"] = True
if not self.target_url:
return redirect("/index/")
else:
return redirect(self.target_url)
@method_decorator(wrapp,name="get")
class Logout(View):
def get(self,request):
del request.session["login"]
request.session.flush()
return redirect('/index/')