Django之Cookie
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 ------