Django中的Cookie--实现登录
Cookie
Cookie 是什么
保存在浏览器端的键值对,让服务器提取有用的信息。
为什么要有 Cookie
因为HTTP请求是无状态的。
无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面的请求响应情况。
状态可以理解为客户端和服务器在某次会话中产生的数据,那无状态的就以为这些数据不会被保留。会话中产生的数据又是我们需要保存的,也就是说要“保持状态”。因此Cookie就是在这样一个场景下诞生。
Cookie 的原理
服务端可以在返回响应的时候 做手脚
在浏览器上写入键值对(Cookie)
浏览器发送请求的时候会自动携带该网站保存在我浏览器的键值对(Cookie)
Chrome 上查看 Cookie
查看Cookie
Django 中操作 Cookie
设置 Cookie
只有响应对象才能设置 Cookie
# 响应对象
rep = HttpResponse(...)
rep = render(request, ...)
rep = redirect(...)
# 不加密方式设置Cookie
rep.set_cookie(key,value,...)
# 加密方式设置Cookie
rep.set_signed_cookie(key,value,salt='加密盐',...)
参数
- key, 键
- value='', 值
- max_age=None, 超时时间
- expires=None, 超时时间(IE requires expires, so set it if hasn't been already.)
- path='/', Cookie生效的路径,/ 表示根路径,特殊的:根路径的 cookie 可以被任何url的页面访问
- domain=None, Cookie 生效的域名
- secure=False, https 传输
- httponly=False 只能 http 协议传输,无法被 JavaScript 获取(不是绝对,底层抓包可以获取到也可以被覆盖)
获取 Cookie
- 不加密的 Cookie 获取:
request.COOKIES['key'] request.COOKIES.get('key')
- 加密的 Cookie 获取
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
- default: 默认值
- salt: 加密盐
- max_age: 后台控制过期时间
删除 Cookie
删除 Cookie 操作大多是在注销时用的,也是 通过响应对象删除。
def logout(request):
# 删除cookie,操作的是响应对象,最后需要返回
rep = redirect("/app01/login/")
rep.delete_cookie("is_login")
return rep
Cookie 版登录代码
from django.shortcuts import render, redirect
# 导入用于装饰器修复技术的包
from functools import wraps
# Create your views here.
# 装饰器函数,用来判断是否登录
def check_login(func):
@wraps(func) # 装饰器修复技术
def inner(request, *args, **kwargs):
ret = request.get_signed_cookie("is_login", default="0", salt="ban")
if ret == "1":
# 已经登录,继续执行
return func(request, *args, **kwargs)
# 没有登录过
else:
# ** 即使登录成功也只能跳转到home页面,现在通过在URL中加上next指定跳转的页面
# 获取当前访问的URL
next_url = request.path_info
return redirect("/app01/login/?next={}".format(next_url))
return inner
def login(request):
if request.method == "POST":
username = request.POST.get("username")
pwd = request.POST.get("pwd")
next_url = request.GET.get("next")
if username == "alex" and pwd == "dsb":
# return redirect("/home/")
# 服务器返回的响应对象
# 通过URL中的next参数指定跳转的页面,如果为空,默认跳转到home页面
if next_url:
rep = redirect(next_url)
else:
print("ban")
rep = redirect("/app01/home/")
# 1. 设置cookie
# rep.set_cookie("is_login", "1")
# 2. 设置加盐cookie,max_age是cookie的生存时间
rep.set_signed_cookie("is_login", "1", salt="ban", max_age=100)
return rep
return render(request, "app01/login.html")
def home(request):
# 获取cookie并判断
# if request.COOKIES.get("is_login", 0) == "1":
# 获取加盐cookie并判断
ret = request.get_signed_cookie("is_login", default="0", salt="ban")
if ret == "1":
return render(request, "app01/home.html")
else:
return redirect("/app01/login/")
# 注销函数
def logout(request):
# 删除cookie,操作的是响应对象,最后需要返回
rep = redirect("/app01/login/")
rep.delete_cookie("is_login")
return rep
@check_login
def index(request):
return render(request, "app01/index.html")
参考:https://www.cnblogs.com/liwenzhou/p/8343243.html
GitHub地址:https://github.com/protea-ban/oldboy/tree/master/s9day71/xiawu