zoukankan      html  css  js  c++  java
  • Cookie和Session

    Cookie的由来:

    因为HTTP协议是无状态;无状态也就是每次的请求都是独立的,比如你不用登录你的账户,你就可以进入需要账户的网站一样,因为对于服务器来说,每次请求都是全新的;

    状态也可以理解为B和S之间的通信产生的数据;无状态则表示数据不会被保留;但是在某些场合下,我们是需要用到这些数据;因此我们需要保持状态,所以cookie就产生了;

    Django中操作Cookie:

    获取Cookie

    request.COOKIES['key']
    request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
    
    # cookie装饰器
    # def crwapper(func):
    # 	@wraps(func)
    # 	def inner(request,*args,**kwargs):  #被装饰器装饰的函数的参数;一个形参
    # 		ret = request.get_signed_cookie("is_login", default="0", salt='加盐')
    # 		if ret == "4":
    # 			ret_new = func(request)
    # 			return ret_new
    # 		else:
    # 			path = request.path_info   #获得当前的路径;不带条件
    # 			request.get_full_path()
    # 			print(path)
    # 			return redirect("/login/?next={}".format(path))
    # 	return inner

    参数:

    • default: 默认值
    • salt: 加密盐
    • max_age: 后台控制过期时间

     

    设置Cookie:

    rep = HttpResponse(...)
    rep = render(request, ...)
    rep = redirect(...)
    rep.set_cookie(key,value,...)
    rep.set_signed_cookie(key,value,salt='加密盐', max_age=None, ...)
    

     注意:设置cookie的时候是用响应来设置

    • key, 键
    • value='', 值
    • max_age=None, 超时时间

     

    rep.set_signed_cookie("is_login","4",salt='加盐',max_age =10)  #max_age 为cookie存在的秒数
    

    删除Cookie:

    ef logout(request):
        rep = redirect("/login/")
        rep.delete_cookie("user")  # 删除用户浏览器上之前设置的usercookie值
        return rep
    

      

    Cookie版登陆校验:

    # cookie版
    # def login(request):
    # 	# GET请求就是请求获取页面;或是搜索引擎
    # 	# username_list=[]
    # 	# pwd_list = []
    # 	error_msg=""
    # 	if request.method == "POST":
    # 		# 否则的话就是POST请求,是提交表单等数据给服务器;request.POST获得请求的数据
    # 		ret = request.POST
    # 		username = ret.get("username", None)
    # 		password = ret.get("pwd", None)
    #
    # 		# 把/login/?next=/index/ 条件拿到
    #
    # 		path =request.get_full_path()   #获得路径 加 条件;
    # 		print(path)  #/login/?next=/index/
    # 		url = request.GET.get("next")   #动态的路径
    #
    # 		# obj = models.UserInfo.objects.all()
    # 		# for i in obj:
    # 		# 	username_list.append(i.name)
    # 		# 	pwd_list.append(i.password)
    # 		# if username in username_list and password in pwd_list:
    # 		if username=="alex" and password=="123":
    # 		# return HttpResponse("登录成功")
    # 		# 给浏览器发送一个响应,带cookie
    # 			if url:
    # 				rep = redirect(url)   #响应的对象
    # 			else:
    # 				rep = redirect("/login_home/")  # 响应的对象
    # 			# rep.set_cookie("is_login","1")
    # 			rep.set_signed_cookie("is_login","4",salt='加盐',max_age =10)  #max_age 为cookie存在的秒数
    # 			# return redirect("http://www.baidu.com")
    # 			return rep
    # 		else:
    # 			error_msg="账号或者密码错误"
    # 	#动态网页,替换的功能
    # 	return render(request, 'login.html',{"error":error_msg})
    

      

    Session

    由于cookie本身是保存在客户端上的(也就是浏览器上的),容易被拦截或窃取;同时最大只能支持4096个字节;

    所以出现了Session,Session是保存在服务器端的,有较高的安全性,但是基于HTTP协议的无状态的特性,要用Cookie起到桥接的作用;

    因此 现在多用 Session 和 Cookie 结合使用;Cookie和Session其实是共通性的东西,不限于语言和框架

     其实 存 和 取 是很简单的,生成随机的字符串,然后把字符串当作K,存的数据作为一个大字典;按照 键值对的形式保存在数据库中;然后 把随机的字符串当作cookie返回给浏览器;这系列的过程全部由Django帮你做;你只需要存和取就行了

    Django中Session相关方法

    # 获取、设置、删除Session中数据
    request.session['k1']
    request.session.get('k1',None)
    request.session['k1'] = 123
    request.session.setdefault('k1',123) # 存在则不设置
    del request.session['k1']
    
    
    # 所有 键、值、键值对
    request.session.keys()
    request.session.values()
    request.session.items()
    request.session.iterkeys()
    request.session.itervalues()
    request.session.iteritems()
    
    # 会话session的key
    request.session.session_key
    
    # 将所有Session失效日期小于当前日期的数据删除
    request.session.clear_expired()
    
    # 检查会话session的key在数据库中是否存在
    request.session.exists("session_key")
    
    # 删除当前会话的所有Session数据
    request.session.delete()
      
    # 删除当前的会话数据并删除会话的Cookie。
    request.session.flush() 
        这用于确保前面的会话数据不可以再次被用户的浏览器访问
        例如,django.contrib.auth.logout() 函数中就会调用它。
    
    # 设置会话Session和Cookie的超时时间
    request.session.set_expiry(value)
        * 如果value是个整数,session会在些秒数后失效。
        * 如果value是个datatime或timedelta,session就会在这个时间后失效。
        * 如果value是0,用户关闭浏览器session就会失效。
        * 如果value是None,session会依赖全局session失效策略。
    

      

     Session 和 cookie 结合的登录校验

    # session和cookie结合版的
    def login(request):
    	# GET请求就是请求获取页面;或是搜索引擎
    	# username_list=[]
    	# pwd_list = []
    	# 将所有的session 失效日期 小于当前的日期的数据 删除;也就是将过期的数据删除;
    	request.session.clear_expired()
    	error_msg = ""
    	if request.method == "POST":
    		# 否则的话就是POST请求,是提交表单等数据给服务器;request.POST获得请求的数据
    		ret = request.POST
    		username = ret.get("username", None)
    		password = ret.get("pwd", None)
    
    		# 把/login/?next=/index/ 条件拿到
    
    		path = request.get_full_path()  # 获得路径 加 条件;
    		print(path)  # /login/?next=/index/
    		url = request.GET.get("next")  # 动态的路径
    
    		# obj = models.UserInfo.objects.all()
    		# for i in obj:
    		# 	username_list.append(i.name)
    		# 	pwd_list.append(i.password)
    		# if username in username_list and password in pwd_list:
    		if username == "alex" and password == "123":
    			# return HttpResponse("登录成功")
    			# 给浏览器发送一个响应,带cookie
    			if url:
    				rep = redirect(url)  # 响应的对象
    			else:
    				rep = redirect("/login_home/")  # 响应的对象
    
    			# 设置一下 session ,生成一段字符串,然后把字符串当做K,
    			# 把存的数据放在大字典里面,大字典当做v,按K-V的形式保存在数据库里面;
    			# Django自动的;帮你生成一段字符串;按K-V的形式保存在数据库里面;
    
    			request.session["is_login"] = "1"
    			# Object of type 'datetime' is not JSON serializable;需要自定义的序列化
    			# day_time = datetime.datetime.utcnow().replace(tzinfo=pytz.utc) + datetime.timedelta(days=3)
    			# request.session.set_expiry(day_time)
    			request.session.set_expiry(7 * 24 * 60 * 60)  # 7s后session失效;失效是指浏览器上的cookie没有了,但是数据库里面还有;
    			return rep
    		else:
    			error_msg = "账号或者密码错误"
    	# 动态网页,替换的功能
    	return render(request, 'login.html', {"error": error_msg})
    
    # session和cookie装饰器
    def crwapper(func):
    	@wraps(func)
    	def inner(request, *args, **kwargs):  # 被装饰器装饰的函数的参数;一个形参
    		ret = request.session.get("is_login", None)
    		if ret == "1":
    			ret_new = func(request)
    			return ret_new
    		else:
    			path = request.path_info  # 获得当前的路径;不带条件
    			request.get_full_path()
    			print(path)
    			return redirect("/login/?next={}".format(path))
    
    	return inner
    

    注销Session和Cookie

    # 注销cookie和session
    def logout(requset):
    	requset.session.flush()
    	return redirect('/login/')
    

      

    Session流程解析

    CBV中加装饰器相关:(详细点我)

    1. 加在CBV视图的get或post方法上

    3. 直接加在视图类上,但method_decorator必须传 name 关键字参数

    如果get方法和post方法都需要登录校验的话就写两个装饰器。

    # 把上面的session装饰器叫到CBV视图上的方法上
    from django.utils.decorators import method_decorator
    from django.views import View
    
    
    # @method_decorator(crwapper,name='post')
    class Login(View):
    
    	@method_decorator(crwapper)  # method_decorator实际上就是把第二个参数request传入你的装饰器的作用;
    	def post(self, request):
    
    		# 否则的话就是POST请求,是提交表单等数据给服务器;request.POST获得请求的数据
    		ret = request.POST
    		username = ret.get("username", None)
    		password = ret.get("pwd", None)
    
    		# 把/login/?next=/index/ 条件(参数)拿到
    
    		path = request.get_full_path()  # 获得路径 加 条件(参数);
    		# request.path_info  获取路径
    
    		print(path)  # /login/?next=/index/
    		url = request.GET.get("next")  # 动态的路径
    
    		# obj = models.UserInfo.objects.all()
    		# for i in obj:
    		# 	username_list.append(i.name)
    		# 	pwd_list.append(i.password)
    		# if username in username_list and password in pwd_list:
    		if username == "alex" and password == "123":
    			# return HttpResponse("登录成功")
    			# 给浏览器发送一个响应,带cookie
    			if url:
    				rep = redirect(url)  # 响应的对象
    			else:
    				rep = redirect("/login_home/")  # 响应的对象
    
    			# 设置一下 session ,生成一段字符串,然后把字符串当做K,
    			# 把存的数据放在大字典里面,大字典当做v,按K-V的形式保存在数据库里面;
    			# Django自动的;帮你生成一段字符串;按K-V的形式保存在数据库里面;
    
    			request.session["is_login"] = "1"
    			# Object of type 'datetime' is not JSON serializable;需要自定义的序列化
    			# day_time = datetime.datetime.utcnow().replace(tzinfo=pytz.utc) + datetime.timedelta(days=3)
    			# request.session.set_expiry(day_time)
    			request.session.set_expiry(7 * 24 * 60 * 60)  # 7s后session失效;失效是指浏览器上的cookie没有了,但是数据库里面还有;
    			return rep
    
    	@method_decorator(crwapper)
    	def get(self, request):
    		request.session.clear_expired()
    		return render(request, 'login.html')
    

      

      

      

    自定义分页:

    # 分页
    
    # # 获取当前的页码
    # page_num = request.GET.get('page')
    # page_num = int(page_num)
    # print(page_num)
    #
    # #获得总的数据
    #
    # total_num = models.Book.objects.all().count()
    #
    # #每一页呈现的数量
    # each_page = 10
    #
    # #获得总页码
    # total_page,n = divmod(total_num,each_page)   # 13//2 --> (6,1)
    # if n:
    # 	total_page+=1
    #
    # # 页面上总共展示多少页码
    # max_page = 9
    #
    # # 在页面张展示的页码 小于 页面上总共展示多少页码数的时候:
    # if total_page <= max_page:
    # 	max_page = total_page
    #
    # # 最大的一半的页码数
    # half_max_page = max_page // 2
    #
    # page_start = page_num - half_max_page
    # page_end = page_num + half_max_page
    # # 当开始页 小于1 :
    # if page_start <=1:
    # 	page_start = 1
    # 	page_end = max_page
    # # 当最后一页 大于 总页数的时候 :
    # if page_end >=total_page:
    # 	page_end = total_page
    # 	page_start = page_end - max_page +1
    #
    #
    # #每一页呈现的数据 的开始和结束
    # data_start = (page_num-1) * each_page
    # data_end  = page_num * each_page
    #
    #
    # #这个是每一页呈现的数据
    # #左闭右开的
    # books = models.Book.objects.all()[data_start:data_end]
    #
    # #在页面张展示的页码
    # total_page_html = []
    #
    # # 首页
    # start_page_html = '<li><a href="/see_book/?page=1">{}</a></li>'.format('首页')
    # total_page_html.append(start_page_html)
    # # 上一页
    # if page_num <= 1:
    # 	Previous_page = '<li class="disabled"><a href="#"><span aria-hidden="true">上一页</span></a></li>'
    # else:
    # 	Previous_page = '<li><a href="/see_book/?page={}"><span aria-hidden="true">上一页</span></a></li>'.format(page_num-1)
    # print(page_num-1)
    # total_page_html.append(Previous_page)
    #
    # for i in range(page_start,page_end+1):
    # 	if i ==page_num:
    # 		page_html = '<li class="active"><a href="/see_book/?page={0}">{0}</a></li>'.format(i)
    # 	else:
    # 		page_html = '<li><a href="/see_book/?page={0}">{0}</a></li>'.format(i)
    # 	total_page_html.append(page_html)
    #
    # #向下一页
    # if page_num >= total_page:
    # 	Next_page = '<li class="disabled"><a href="#"><span aria-hidden="true">下一页</span></a></li>'.format(total_page)
    # else:
    # 	Next_page = '<li><a href="/see_book/?page={}"><span aria-hidden="true">下一页</span></a></li>'.format(page_num+1)
    # total_page_html.append(Next_page)
    #
    # #尾页
    # end_page_html = '<li><a href="/see_book/?page={1}">{0}</a></li>'.format('尾页',total_page)
    # total_page_html.append(end_page_html)
    #
    # total_page_html = ''.join(total_page_html)
    

      

      

  • 相关阅读:
    计算机通信
    笔记0402
    笔记0414
    vb6 VS vb.net int数据类型
    jQuery好网站
    jQuery实现图片翻滚
    jQuery获取一组单选按钮的值
    Redhat安装、使用及服务器应用FAQ
    js判断变量是否赋值(存在)
    IDE 与SATA区别
  • 原文地址:https://www.cnblogs.com/zenghui-python/p/10931773.html
Copyright © 2011-2022 走看看