Cookie是保存在用户浏览器端的一个键值对。
Cookie是存在用户浏览器端的。保存用户登录的凭证。
服务端可以向用户浏览器端写Cookie。
客户端每次发请求时,会携带Cookie去。
Cookie 的发送是放在请求头里的数据。(request.Cookies)
在响应头里,也是有Cookie的。是set_Cookie。
在Cookie的应用中,有比如在浏览器登录一次,就会记住密码,下次在登录时,就不用再输出密码,密码是自动填充直接登录,这也是Cookie在做的。
实现主页面在没有登录状态下,要强制登录的功能。
要在主页面的函数中,先进行Cookie的认证。
要先去请求的Cookie中找凭证。
#去Cookie中get拿取值
tk = request.COOKIES.get("ticket")
#对拿到的tk进行判断,如果是tk没有值,为None的话,就要去用户登录。
if not tk:
return redirect("/login/")
def classes(request):
"""
链接数据库
:param request: 用户请求的相关的所有信息(对象)
:return:
"""
# 去Cookie中get拿取值
tk = request.COOKIES.get("ticket")
# 对拿到的tk进行判断,如果是tk没有值,为None的话,就要去用户登录。
if not tk:
return redirect("/login/")
else:
conn = pymysql.connect(host="127.0.0.1",port=3306,user='root',passwd='redhat',db='weibo',charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) #改为字典
cursor.execute("select nid,title from classes")
class_list = cursor.fetchall()
cursor.close()
conn.close()
return render(request, "classes.html",{"class_lsit":class_list})
在login的函数中:
def login(request):
"""
处理用户请求,并返回内容
:param request: 用户请求的相关的所有信息(对象)
:return:
"""
#通过请求方式,返回不同的信息
if request.method == "GET":
return render(request,"login.html")
else:
print(request.POST) #用户POST提交的数据,(请求体里的数据)
username = request.POST.get("username") #取出字典里的数据。
password = request.POST.get("password") #取出字典里的数据。
if username == "yanyan" and password == "1314":
# 可以用 redirect 重定向,跳转到指定页面。
obj = redirect("/index/")
#给浏览器回写Cookie,这是请求的Cookie
obj.set_cookie("ticket","aaaaa")
return obj
else:
#登录失败
return render(request,"login.html",{"msg":"username or password is error"})
响应头的Cookie:
def test(request):
#响应返回的数据
obj = HttpResponse("OK")
#返回给用户的Cookie,在响应头中体现。
obj.set_cookie("k1":"v1")
return obj
Cookie设置超时时间:
set_cookie("ticket","asd",max_age=10 )
max_age是设置超时时间的。单位是秒。
expires也是设置超时时间的,是设置具体的超时日期的。
def login(request):
if request.method == "GET":
return render(request,"login.html")
else:
htmlusername = request.POST.get("username")
htmlpassword = request.POST.get("password")
userinfo_list = sqlheper.get_list("select username,password from userinfo where username = %s",[htmlusername,])
for item in userinfo_list:
print(item["username"],item["password"])
if len(htmlpassword)>0:
if htmlusername == item["username"] and htmlpassword == item["password"]:
obj = redirect("/index/")
ct = datetime.datetime.utcnow()
#设置当前时间
v = timedelta(seconds=10)
#时间的加减用timedelta 来操作
value = ct+v
obj.set_cookie("ticket","yanzheng",max_age=10)
obj.set_cookie("ticket","yanzheng",expires=value) //这里的yanzheng是明文的
return obj
else:
return render(request,"login.html",{"msg":"username or password is error"})
else:
return render(request, "login.html", {"msg": "password 不能为空"})
Cookie 的path应用:
path是用来指定Cookie可以读取的url。比如有两个函数,分别设置不同的Cookie值,这时在指定path,那么在执行那个函数的时候,Cookie就不会拿取所有,而是只去拿取path指定的值。
def test1(request):
print(request.COOKIES)
obj = HttpResponse("OK")
obj.set_cookie("k2","v2",path="/test1")
return obj
def test2(request):
print(request.COOKIES)
#拿取所有的Cookie值
obj = HttpResponse("ok")
return obj
Cookie 的 domain :
domain 是设置在访问某域名的时候才会获取的Cookie值。
一般只有在写SSO后者是统一认证登录时,会涉及到多域名时,才会设置domain。
Cookie 的 httponly :
httponly 是做安全相关的事情。httponly表示定义的Cookie只能通过http来发送请求。
如果把Cookie写到用户的浏览器端,用户是可以获取你的Cookie并操作的。但是,如果把httponly的值写成True的话,用户在浏览器端是找不到Cookie的,并且没有权限去操作这个Cookie。因为它只给http请求发送请求时应用,所以只能自http请求中传入,js代码无法获取。但可以通过抓包来拿取。
Cookie 的 secure:
secure 是给https提供的功能。 如果需要secure提供服务,比如做网站相关,要将值改为True。
Cookie 的 扩展签名:
签名就是将我们明文的Cookie值进行一个加密操作。
obj.set_signed_cookie() 就是可以设置签名的Cookie。而这里主要的参数就salt。salt的值就是签名,也可以理解为加密的值。而在接受端,也不再是request.COOKIES.get("ticket") 啦,而是request.get_signed_cookie("ticket",salt="Code Cookie"),因为在Cookie的发送端的login函数里,是我们自己加密的,所以在接收端这么classes函数就是自己解密。
views.py 中login发送Cookie的函数的示例:
def login(request):
if request.method == "GET":
return render(request,"login.html")
else:
htmlusername = request.POST.get("username")
htmlpassword = request.POST.get("password")
userinfo_list = sqlheper.get_list("select username,password from userinfo where username = %s",[htmlusername,])
for item in userinfo_list:
print(item["username"],item["password"])
if len(htmlpassword)>0:
if htmlusername == item["username"] and htmlpassword == item["password"]:
obj = redirect("/index/")
# obj.set_cookie("ticket","yanzheng",max_age=10)
obj.set_signed_cookie("ticket","Cookie",salt="Code Cookie",max_age=10) #这里就设置了salt
return obj
else:
return render(request,"login.html",{"msg":"username or password is error"})
else:
return render(request, "login.html", {"msg": "password 不能为空"})
views.py 中classes或index接受Cookie的函数的示例:
def classes(request):
tk = request.get_signed_cookie("ticket",salt="Code Cookie") #接受Cookie的方式
print("classes",tk)
if not tk:
return redirect("/login/")
else:
conn = pymysql.connect(host="127.0.0.1",port=3306,user='root',passwd='redhat',db='weibo',charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) #改为字典
cursor.execute("select nid,title from classes")
class_list = cursor.fetchall()
cursor.close()
conn.close()
return render(request, "classes.html",{"class_lsit":class_list})
在前端查看ticket的状态:
Cookie 自己定义签名的规则:
使加密规则文件生效,就在settings中加上自己写的签名规则的类。
因为在源码里,这个规则是默认用的类是TimestampSigner的方法。
创建一个py文件,名change.py:
from django.core.signing import TimestampSigner
class MySigner(TimestampSigner):
def sign(self, value):
"""
加密
:param value: 加密的方式就是在值的后面加123,
:return:
"""
return value + '123'
def unsign(self, value, max_age=None):
"""
解密
:param value:
:param max_age:
:return:
"""
v = value[0:-3] #这里解密的值的取值之取到Cookie,所以后端的值,只能拿到Cookie,那个加密的123是拿不到的。
return v
在Django的Settings配置文件中,添加:
SIGNING_BACKEND = 'change.MySigner' #这样就指定了自己的加密方式
xxx为MySigner的文件路径。
结果展示:
------ END ------