摘要:服务器是怎么相信知道我们的状态信息?前人为浏览器设置cookie,后人引入session的技术?
看完本文,你将学会如何为你的用户设置cookie和保存session
本文小细节:
1.我们使用Chrome浏览器,打开开发者工具。application-cookie可以看到cookie 2.在我们的django中 浏览器请求会自带cookie,我们Django会自动获取cookie 封装到 request.COOKIES中 {}
3.django 默认cookie时效 为两周
4.request.session['name'] = 'jason'
#不是立马设置,等到return走到中间件才设置
Cookie与session区别
TCP/IP是无连接无状态的,每次请求带你如初见,要想保存客户端信息就要用到一个技术---cookie
简单的说一个网站容不下过多cookie,最多20个,每个4k
有些大型网站不满足 需要更多的信息 于是session就拿着浏览器传来的cookie去自己的“字典”里去匹配,拿到更多的信息
所以后面cookie充当身份ID,真正信息往往在数据库中
区别1:存放位置 :cookie浏览器 session服务器
区别2:大小:cookie有大小限制 session没有
区别3:用途:Cookie用来辨别身份 session用来匹配信息
区别4:安全:cookie容易被拦截不安全 session存在服务器数据往往安全
cookie
Django获取
request.COOKIES['key'] request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
参数:
default: 默认值
salt: 加密盐
max_age: 后台控制过期时间
设置cookie
在renner对象上设置
render_obj=HttpResponse("")
render_obj.set_cookie("k","v",expires=7*24*3600) #expires过期时间
return render_obj
参数
参数: 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
rep.delete_cookie("user") return rep
登陆示例
def check_login(func): @wraps(func) def inner(request, *args, **kwargs): next_url = request.get_full_path() if request.get_signed_cookie("login", salt="SSS", default=None) == "yes": # 已经登录的用户... return func(request, *args, **kwargs) else: # 没有登录的用户,跳转刚到登录页面 return redirect("/login/?next={}".format(next_url)) return inner def login(request): if request.method == "POST": username = request.POST.get("username") passwd = request.POST.get("password") if username == "xxx" and passwd == "dashabi": next_url = request.GET.get("next") if next_url and next_url != "/logout/": response = redirect(next_url) else: response = redirect("/class_list/") response.set_signed_cookie("login", "yes", salt="SSS") return response return render(request, "login.html")
session
我们为session赋值的时候,客户端不会立马生效,需要Django返回走中间件的时候才会生效
Django为我们封好了session, 我们直接使用
session常用:
request.session["k"] #当前用户查询出value值 request.session["k"]=v #为当前用户设置k,v值 request.session.session_key #会话session的key request.session.delete() # 只删除数据库里的 request.session.exists("session_key") # 检查会话session的key在数据库中是否存在 request.session.flush() #删除用户和数据库里的 request.session.set_expiry(value) #设置超时时间 int 多少秒之后 datatime,timedelta 这个时间后 0 关闭浏览器 None 默认的
其他操作:
request.session.get("k",""v",default="默认") #了解 request.session.setdefault('k1',123) #没有才设置 #去数据库查询当前用户所有的数据 request.session.keys() request.session.values() request.session.items() request.session.iterkeys() request.session.itervalues() request.session.iteritems() # 将所有Session失效日期小于当前日期的数据删除 request.session.clear_expired()
Django存放session位置
Session设值的时候具体流程
1.生成随机字符串 2.向服务器插入数据 3.去客户端设置cookie随机字符串(方便理解,实际上是中间件的时候设置)
request拿到session的具体流程
#1.拿到服务器返回的session
# 2.如果比对成功 会将当前随机字符串对应的数据赋值给request.session
# 3.通过request.session操作该数据(数据不存在也不会影响我们的业务逻辑)
示例:登陆实例,没有session就回到的登陆界面
def auth(func): def inner(request,*args,**kwargs): if not request.session.session_key: return redirect("/reg") else : return func(request,*args,**kwargs) return inner def reg(request): if request.method=="POST": print("我打印下 看你的session 是多少",request.session.session_key) request.session[request.POST.get("username")]=request.POST.get("password") return render(request, "home.html") return render(request,"register.html")
给CBV加装饰器判断是否是有session的用户
@method_decorator(my_decorator,name="get") 在类上 在dispath上 @method_decorator(login_auth) # 第三种 get和post都会被装饰 def dispatch(self, request, *args, **kwargs): super().dispatch(request,*args,**kwargs) @method_decorator(login_auth) # 第一种 def get(self,request): return HttpResponse('get')