• Cookie、Session和自定义分页


    Django中操作Cookie


    目前市面上做登录的两种方式:
    1. 加盐的Cookie 数据都保存在客户的浏览器上,服务端没什么压力
    2. Cookie+Session 数据都保存在服务端,服务端会有一定的数据压力

     Cookie
    就是保存在浏览器端的键值对

    1. 服务端可以在浏览器上设置COOKIE 保存在浏览器上的
    2. 每次请求会携带COOKIE
    3. Cookie是有效时间的
    4. 可以用来做登录或其他事情


    现在做登录相关的:
    1. 用加盐的cookie

    2. cookie+session

    获取Cookie

    request.COOKIES['key'] requeste.COOKIE.get('key',None(如果key 没有对应的值 返回None)) 未加盐的情况看下,用此方法 设置端发送端设置为set_cookie的时候
    用这种方式接收数据 request.get_signed_cookie(key, default
    =RAISE_ERROR(设置取不到的情况显示什么), salt='', max_age=None)
    设置cookie端用set_signed_cookie的时候用这种方式接收数据

    参数:

    • default: 默认值
    • salt: 加密盐
    • max_age: 后台控制过期时间(时间值为)  这个只要有一端设置了时间之后就按这个时间来监控,当时间超出后就会失效       默认是两周

    设置Cookie

    rep = HttpResponse(...)
    rep = render(request, ...)
    
    rep.set_cookie(key,value,...)
    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的页面访问  就是路径设置好了  他相关的页面就能得到相关的cookie数据
    •     如path='/index1/'  然后就是网页中根是index1的才能得到这个cookie数据  详见下图
    • domain=None, Cookie生效的域名
    • secure=False, https传输
    • httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

    删除Cookie

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

    Cookie版登陆校验

    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")
    View Code

    Session

    Session

    Session是保存在服务端的“键值对”(数据)
    Session必须依赖于Cookie

    要想使用session就要先登录就要配置好数据库


    要做的事儿:
    1. 生成随机字符串
    2. 回给浏览器,让它写到Cookie   如生成的特殊字符串 sadadsadsadsa 记录到Cookie  --> response对象来处理
    3. 我自己保留一份,作为一个KEY,存到一个地方,KEY后面对应一个保存用户相关信息的键值对   

    类似于data= {
        sadadsadsadsa: {“k1": "v1"}
        }  详情看下图

    Django中默认支持Session,其内部提供了5种类型的Session供开发者使用:

    • 数据库(默认)
    • 缓存
    • 文件
    • 缓存+数据库
    • 加密cookie

      • 登录后页面看到的session信息,在请求头上  意思是将session信息返回给了浏览器端

    数据库Session

    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)

    缓存Session

    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
    SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置  购物车

    文件Session

    SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
    SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 

    缓存+数据库

    SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎  大型网站

    加密Cookie Session

    SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎

    其他公用设置项:

    复制代码
    SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
    SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
    SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
    SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
    SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
    SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
    SESSION_SAVE_EVERY_REQUEST = True        通常大网站都会设置每次请求来都会保存新的
                           # 是否每次请求都保存Session,默认修改之后才保存(默) session实时更新,记录最后登录的session信息
    复制代码

    不管你怎么设置Session,使用方式都一样:

    复制代码
    def index(request):
        # 获取、设置、删除Session中数据            注意无论是设置还是获取session  都是用request.session
        request.session['k1']=user    设置session
        request.session.get('k1',None)  获取session   这一步做了三个操作,先取出用户从浏览器带过来的sessionid即他的随机字符串,
                         取出来之后去服务器的数据库中查找有没有这个sessionID 有的话 在取出 “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的随机字符串 request.session.session_key 能够得到用户的session值 如wmxbnpzelmkqk6ninfxt1708jxl89qn7 # 将所有Session失效日期小于当前日期的数据删除 request.session.clear_expired() # 检查 用户session的随机字符串 在数据库中是否 request.session.exists("session_key") # 删除当前用户的所有Session数据 request.session.delete("session_key") request.session.set_expiry(value) * 如果value是个整数,session会在些秒数后失效。 * 如果value是个datatime或timedelta,session就会在这个时间后失效。 * 如果value是0,用户关闭浏览器session就会失效。 * 如果value是None,session会依赖全局session失效策略。
    复制代码

    课后练习:Session版登陆验证

    CBV中加装饰器相关

    from django.utils.decorators import method_decorator

    1. 加在get或post方法上

    复制代码
    class LoginView(View):
        
        def dispatch(self, request, *args, **kwargs):
            return super(LoginView,self).dispatch(request, *args, **kwargs)
    
        def get(self,request):
            return render(request,'login.html')
    
        @method_decorator(test)
        def post(self,request):
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
            if user == 'alex' and pwd == "alex3714":
                # 生成随机字符串
                # 写浏览器cookie: session_id: 随机字符串
                # 写到服务端session:
                # {
                #     "随机字符串": {'user_info':'alex}
                # }
                request.session['user_info'] = "alex"
                return redirect('/index/')
            return render(request, 'login.html')
    复制代码

    2. 加在dispatch方法上

    复制代码
    class LoginView(View):
    
        @method_decorator(test)
        def dispatch(self, request, *args, **kwargs):
            return super(LoginView, self).dispatch(request, *args, **kwargs)
    
    
        def get(self, request):
            return render(request, 'login.html')
    
    
        def post(self, request):
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
            if user == 'alex' and pwd == "alex3714":
                # 生成随机字符串
                # 写浏览器cookie: session_id: 随机字符
                # 写到服务端session:
                # {
                #     "随机字符串": {'user_info':'alex}
                # }
                request.session['user_info'] = "alex"
                return redirect('/index/')
            return render(request, 'login.html')
    复制代码

    3. 加在类上

    复制代码
    @method_decorator(test,name='get')
    class LoginView(View):
        
        def dispatch(self, request, *args, **kwargs):
            return super(LoginView,self).dispatch(request, *args, **kwargs)
    
        def get(self,request):
            return render(request,'login.html')
    
        def post(self,request):
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
            if user == 'alex' and pwd == "alex3714":
                # 生成随机字符串
                # 写浏览器cookie: session_id: 随机字符串
                # 写到服务端session:
                # {
                #     "随机字符串": {'user_info':'alex}
                # }
                request.session['user_info'] = "alex"    注意这里边是中括号
                return redirect('/index/)
            return render(request, 'login.html')
    复制代码

    4. CSRF Token相关只能加到dispatch方法上

    备注:

    • csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
    • csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
    复制代码
    from django.views.decorators.csrf import csrf_exempt, csrf_protect
    
    class LoginView(View):
        @method_decorator(csrf_exempt)
        def dispatch(self, request, *args, **kwargs):
            return super(LoginView,self).dispatch(request, *args, **kwargs)
    
        def get(self,request):
            return render(request,'login.html')
    
        def post(self,request):
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
            if user == 'alex' and pwd == "alex3714":
                # 生成随机字符串
                # 写浏览器cookie: session_id: 随机字符串
                # 写到服务端session:
                # {
                #     "随机字符串": {'user_info':'alex}
                # }
                request.session['user_info'] = "alex"
                return redirect('/index/')
            return render(request, 'login.html')
    复制代码

    自定义分页

    data = []
    
    for i in range(1, 302):
        tmp = {"id": i, "name": "alex-{}".format(i)}
        data.append(tmp)
    
    print(data)
    
    
    def user_list(request):
    
        # user_list = data[0:10]
        # user_list = data[10:20]
        try:
            current_page = int(request.GET.get("page"))
        except Exception as e:
            current_page = 1
    
        per_page = 10
    
        # 数据总条数
        total_count = len(data)
        # 总页码
        total_page, more = divmod(total_count, per_page)
        if more:
            total_page += 1
    
        # 页面最多显示多少个页码
        max_show = 11
        half_show = int((max_show-1)/2)
    
        if current_page <= half_show:
            show_start = 1
            show_end = max_show
        else:
            if current_page + half_show >= total_page:
                show_start = total_page - max_show
                show_end = total_page
            else:
                show_start = current_page - half_show
                show_end = current_page + half_show
    
        # 数据库中获取数据
        data_start = (current_page - 1) * per_page
        data_end = current_page * per_page
    
        user_list = data[data_start:data_end]
    
        # 生成页面上显示的页码
        page_html_list = []
        # 加首页
        first_li = '<li><a href="/user_list/?page=1">首页</a></li>'
        page_html_list.append(first_li)
        # 加上一页
        if current_page == 1:
            prev_li = '<li><a href="#">上一页</a></li>'
        else:
            prev_li = '<li><a href="/user_list/?page={}">上一页</a></li>'.format(current_page - 1)
        page_html_list.append(prev_li)
        for i in range(show_start, show_end+1):
            if i == current_page:
                li_tag = '<li class="active"><a href="/user_list/?page={0}">{0}</a></li>'.format(i)
            else:
                li_tag = '<li><a href="/user_list/?page={0}">{0}</a></li>'.format(i)
            page_html_list.append(li_tag)
    
        # 加下一页
        if current_page == total_page:
            next_li = '<li><a href="#">下一页</a></li>'
        else:
            next_li = '<li><a href="/user_list/?page={}">下一页</a></li>'.format(current_page+1)
        page_html_list.append(next_li)
    
        # 加尾页
        page_end_li = '<li><a href="/user_list/?page={}">尾页</a></li>'.format(total_page)
        page_html_list.append(page_end_li)
    
        page_html = "".join(page_html_list)
    
        return render(request, "user_list.html", {"user_list": user_list, "page_html": page_html})
    稳扎稳打版
    class Pagination(object):
        def __init__(self, current_page, total_count, base_url, per_page=10, max_show=11):
            """
            :param current_page: 当前页
            :param total_count: 数据库中数据总数
            :param per_page: 每页显示多少条数据
            :param max_show: 最多显示多少页
            """
            try:
                current_page = int(current_page)
            except Exception as e:
                current_page = 1
    
            self.current_page = current_page
            self.total_count = total_count
            self.base_url = base_url
            self.per_page = per_page
            self.max_show = max_show
    
            # 总页码
            total_page, more = divmod(total_count, per_page)
            if more:
                total_page += 1
            
            half_show = int((max_show - 1) / 2)
            self.half_show = half_show
            self.total_page = total_page
    
        @property
        def start(self):
            return (self.current_page - 1) * self.per_page
    
        @property
        def end(self):
            return self.current_page * self.per_page
    
        def page_html(self):
    
            if self.current_page <= self.half_show:
                show_start = 1
                show_end = self.max_show
            else:
                if self.current_page + self.half_show >= self.total_page:
                    show_start = self.total_page - self.max_show
                    show_end = self.total_page
                else:
                    show_start = self.current_page - self.half_show
                    show_end = self.current_page + self.half_show
    
                    # 生成页面上显示的页码
            page_html_list = []
            # 加首页
            first_li = '<li><a href="{}?page=1">首页</a></li>'.format(self.base_url)
            page_html_list.append(first_li)
            # 加上一页
            if self.current_page == 1:
                prev_li = '<li><a href="#">上一页</a></li>'
            else:
                prev_li = '<li><a href="{0}?page={1}">上一页</a></li>'.format(self.base_url, self.current_page - 1)
            page_html_list.append(prev_li)
            for i in range(show_start, show_end + 1):
                if i == self.current_page:
                    li_tag = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
                else:
                    li_tag = '<li><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
                page_html_list.append(li_tag)
    
            # 加下一页
            if self.current_page == self.total_page:
                next_li = '<li><a href="#">下一页</a></li>'
            else:
                next_li = '<li><a href="{0}?page={1}">下一页</a></li>'.format(self.base_url, self.current_page + 1)
            page_html_list.append(next_li)
    
            # 加尾页
            page_end_li = '<li><a href="{0}?page={1}">尾页</a></li>'.format(self.base_url, self.total_page)
            page_html_list.append(page_end_li)
    
            return "".join(page_html_list)
    封装保存版
    def user_list(request):
        pager = Pagination(request.GET.get("page"), len(data), request.path_info)
        user_list = data[pager.start:pager.end]
        page_html = pager.page_html()
        return render(request, "user_list.html", {"user_list": user_list, "page_html": page_html})
    封装保存版使用指南

    扩展:

    Django内置分页

    from django.shortcuts import render
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    
    L = []
    for i in range(999):
        L.append(i)
    
    def index(request):
        current_page = request.GET.get('p')
    
        paginator = Paginator(L, 10)
        # per_page: 每页显示条目数量
        # count:    数据总个数
        # num_pages:总页数
        # page_range:总页数的索引范围,如: (1,10),(1,200)
        # page:     page对象
        try:
            posts = paginator.page(current_page)
            # has_next              是否有下一页
            # next_page_number      下一页页码
            # has_previous          是否有上一页
            # previous_page_number  上一页页码
            # object_list           分页之后的数据列表
            # number                当前页
            # paginator             paginator对象
        except PageNotAnInteger:
            posts = paginator.page(1)
        except EmptyPage:
            posts = paginator.page(paginator.num_pages)
        return render(request, 'index.html', {'posts': posts})
    内置分页view部分
    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    <ul>
        {% for item in posts %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>
    
    <div class="pagination">
          <span class="step-links">
            {% if posts.has_previous %}
                <a href="?p={{ posts.previous_page_number }}">Previous</a>
            {% endif %}
              <span class="current">
                Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
              </span>
              {% if posts.has_next %}
                  <a href="?p={{ posts.next_page_number }}">Next</a>
              {% endif %}
          </span>
    
    </div>
    </body>
    </html>
    View Code

    上课老师例题讲解

    在只用cookie时的登录验证的装饰期

    要登录试图函数,给他绑定装饰器,用于判断是否登录过

    #去到装饰器中判断是否登录过(即是否含有登录后封装存入的cookie键值对)
    @swaper
    def index1(request):
        user=request.get_signed_cookie('user',salt='s8')
        return render(request,'index1.html',{'user':user})

    装饰器:主要是通过判断cookie的键是否有对应的值

    
    
    from functools import wraps

    def
    swaper(func):
      @wraps(func) 加上这个能够保持被装饰的函数的 __name__ __doc__ 的属性不被inner覆盖
    def inner(request,*args,**kwargs): #获取当前的全部地址信息 nex=request.get_full_path() #取出cookie值,下边进行判断是否有cookie的键值对 ret=request.get_signed_cookie('user',None,salt='s8') #存入cookie的时候 加盐了去的时候也要加盐 print(ret)#如果有值的话 #表示用户已经登录 if ret: #直接返回要登录的地址 return func(request,*args,**kwargs) else:#没有值的话就去登录 print('滚去登录!') #将地址拼上,放进去, return redirect('/login/?next={}'.format(nex))# return inner

    登录试图函数

    def login (request):
        #将拼上的数据取出next的值,即院访问的地址
        nex=request.GET.get('next')
        #这里的nex是 /index1/
        if request.method=='POST':
            print('aa')
    
            name=request.POST.get('name')
            psw=request.POST.get('psw')
            if name=='alex' and psw=='123':
                print('用户名密码正确')
                req=redirect(nex)
                #加上cookie键值对
                req.set_signed_cookie('user',name,salt='s8')
                print(nex)
                #返回
                return req
        return render(request,'login.html')

     cookie 和session的区别和联系

    一、Session的概念

    Session 是存放在服务器端的,类似于Session结构来存放用户数据,当浏览器 第一次发送请求时,服务器自动生成了一个Session和一个Session ID用来唯一标识这个Session,并将其通过响应发送到浏览器。当浏览器第二次发送请求,会将前一次服务器响应中的Session ID放在请求中一并发送到服务器上,服务器从请求中提取出Session ID,并和保存的所有Session ID进行对比,找到这个用户对应的Session。

    一般情况下服务器会在一定时间内(默认30分钟)保存这个 Session过了时间限制就会销毁这个Session。在销毁之前,程序员可以将用户的一些数据以Key和Value的形式暂时存放在这个 Session中。当然,也有使用数据库将这个Session序列化后保存起来的,这样的好处是没了时间的限制,坏处是随着时间的增加,这个数据 库会急速膨胀,特别是访问量增加的时候。一般还是采取前一种方式,以减轻服务器压力。

    二、Session的客户端实现形式(即Session ID的保存方法

    一般浏览器提供了两种方式来保存,还有一种是程序员使用html隐藏域的方式自定义实现:

    [1] 使用Cookie来保存,这是最常见的方法,本文“记住我的登录状态”功能的实现正式基于这种方式的。服务器通过设置Cookie的方式将Session ID发送到浏览器。如果我们不设置这个过期时间,那么这个Cookie将不存放在硬盘上,当浏览器关闭的时候,Cookie就消失了,这个Session ID就丢失了。如果我们设置这个时间为若干天之后,那么这个Cookie会保存在客户端硬盘中,即使浏览器关闭,这个值仍然存在,下次访问相应网站时,同 样会发送到服务器上。

    [2] 使用URL附加信息的方式,也就是像我们经常看到JSP网站会有aaa.jsp?JSESSIONID=*一样的。这种方式和第一种方式里面不设置Cookie过期时间是一样的。

    [3] 第三种方式是在页面表单里面增加隐藏域,这种方式实际上和第二种方式一样,只不过前者通过GET方式发送数据,后者使用POST方式发送数据。但是明显后者比较麻烦。

    cookie与session的区别:

    cookie数据保存在客户端,session数据保存在服务器端。

    简 单的说,当你登录一个网站的时候,如果web服务器端使用的是session,那么所有的数据都保存在服务器上面,客户端每次请求服务器的时候会发送 当前会话的sessionid,服务器根据当前sessionid判断相应的用户数据标志,以确定用户是否登录,或具有某种权限。由于数据是存储在服务器 上面,所以你不能伪造,但是如果你能够获取某个登录用户的sessionid,用特殊的浏览器伪造该用户的请求也是能够成功的。sessionid是服务 器和客户端链接时候随机分配的,一般来说是不会有重复,但如果有大量的并发请求,也不是没有重复的可能性,我曾经就遇到过一次。登录某个网站,开始显示的 是自己的信息,等一段时间超时了,一刷新,居然显示了别人的信息。

    如果浏览器使用的是 cookie,那么所有的数据都保存在浏览器端,比如你登录以后,服务器设置了 cookie用户名(username),那么,当你再次请求服务器的时候,浏览器会将username一块发送给服务器,这些变量有一定的特殊标记。服 务器会解释为 cookie变量。所以只要不关闭浏览器,那么 cookie变量便一直是有效的,所以能够保证长时间不掉线。如果你能够截获某个用户的 cookie变量,然后伪造一个数据包发送过去,那么服务器还是认为你是合法的。所以,使用 cookie被攻击的可能性比较大。如果设置了的有效时间,那么它会将 cookie保存在客户端的硬盘上,下次再访问该网站的时候,浏览器先检查有没有 cookie,如果有的话,就读取该 cookie,然后发送给服务器。如果你在机器上面保存了某个论坛 cookie,有效期是一年,如果有人入侵你的机器,将你的 cookie拷走,然后放在他的浏览器的目录下面,那么他登录该网站的时候就是用你的的身份登录的。所以 cookie是可以伪造的。当然,伪造的时候需要主意,直接copy cookie文件到 cookie目录,浏览器是不认的,他有一个index.dat文件,存储了 cookie文件的建立时间,以及是否有修改,所以你必须先要有该网站的 cookie文件,并且要从保证时间上骗过浏览器,曾经在学校的vbb论坛上面做过试验,copy别人的 cookie登录,冒用了别人的名义发帖子,完全没有问题。

    Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID 为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一 SessionID提交到服务器端,来存取Session数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用Cookie,那么Session也会失效。

    服务器也可以通过URL重写的方式来传递SessionID的值,因此不是完全依赖Cookie。如果客户端Cookie禁用,则服务器可以自动通过重写URL的方式来保存Session的值,并且这个过程对程序员透明。

    可以试一下,即使不写Cookie,在使用request.getCookies();取出的Cookie数组的长度也是1,而这个Cookie的名字就是JSESSIONID,还有一个很长的二进制的字符串,是SessionID的值。

    三:Session与Cookie区别和联系:

    Cookies是属于Session对象的一种。但有不同,Cookies不会占服务器资源是存在客服端内存或者一个cookie的文本文件中;而“Session”则会占用服务器资源。所以,尽量不要使用Session,而使用Cookies。但是我们一般认为cookie是不可靠的,session是可靠地,但是目前很多著名的站点也都以来cookie。有时候为了解决禁用cookie后的页面处理,通常采用url重写技术,调用session中大量有用的方法从session中获取数据后置入页面。

    Cookies与Session的应用场景: 
    Cookies的安全性能一直是倍受争议的。虽然Cookies是保存在本机上的,但是其信息的完全可见性且易于本地编辑性,往往可以引起很多的安全问题。所以Cookies到底该不该用,到底该怎样用,就有了一个需要给定的底线。

    先来看看,网站的敏感数据有哪些。

    登陆验证信息。一般采用Session(“Logon”)=true or false的形式。 
    用户的各种私人信息,比如姓名等,某种情况下,需要保存在Session里 
    需要在页面间传递的内容信息,比如调查工作需要分好几步。每一步的信息都保存在Session里,最后在统一更新到数据库。

    当然还会有很多,这里列举一些比较典型的 
    假如,一个人孤僻到不想碰Session,因为他认为,如果用户万一不小心关闭了浏览器,那么之前保存的数据就全部丢失了。所以,他出于好意,决定把这些用Session的地方,都改成用Cookies来存储,这完全是可行的,且基本操作和用Session一模一样。那么,下面就针对以上的3个典型例子,做一个分析 
    很显然,只要某个有意非法入侵者,知道该网站验证登陆信息的Session变量是什么,那么他就可以事先编辑好该Cookies,放入到Cookies目录中,这样就可以顺利通过验证了。这是不是很可怕? 
    Cookies完全是可见的,即使程序员设定了Cookies的生存周期(比如只在用户会话有效期内有效),它也是不安全的。假设,用户忘了关浏览器 或者一个恶意者硬性把用户给打晕,那用户的损失将是巨大的。 
    这点如上点一样,很容易被它人窃取重要的私人信息。但,其还有一个问题所在是,可能这些数据信息量太大,而使得Cookies的文件大小剧增。这可不是用户希望所看到的。

    显然,Cookies并不是那么一块好啃的小甜饼。但,Cookies的存在,当然有其原因。它给予程序员更多发挥编程才能的空间。所以,使用Cookies改有个底线。这个底线一般来说,遵循以下原则。 
    不要保存私人信息。 
    任何重要数据,最好通过加密形式来保存数据(最简单的可以用URLEncode,当然也可以用完善的可逆加密方式,遗憾的是,最好不要用md5来加密)。 
    是否保存登陆信息,需有用户自行选择。 
    长于10K的数据,不要用到Cookies。 
    也不要用Cookies来玩点让客户惊喜的小游戏。

    四、cookie最典型的应用是:

    (一):判断用户是否登陆过网站,以便下次登录时能够直接登录。如果我们删除cookie,则每次登录必须从新填写登录的相关信息。

    (二):另一个重要的应用是“购物车”中类的处理和设计。用户可能在一段时间内在同一家网站的不同页面选择不同的商品,可以将这些信息都写入cookie,在最后付款时从cookie中提取这些信息,当然这里面有了安全和性能问题需要我们考虑了。

    Django中的session中间件  源码解析

     第三个  self.SessionStore对应的内容

    查找顺序是

    知识点:
    import views 这个是必须变量
    import_module "views" 这个可以引用字符串

    class SessionMiddleware(MiddlewareMixin):
        def __init__(self, get_response=None):
            self.get_response = get_response
            engine = import_module(settings.SESSION_ENGINE)
            self.SessionStore = engine.SessionStore
    
        def process_request(self, request):
            session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
            request.session = self.SessionStore(session_key)   
        #request.session是 类下实例化的一个对像
    def process_response(self, request, response): """ If request.session was modified, or if the configuration is to save the session every time, save the changes and set a session cookie or delete the session cookie if the session has been emptied. """ try: accessed = request.session.accessed modified = request.session.modified empty = request.session.is_empty() except AttributeError: pass else: # First check if we need to delete this cookie. # The session should be deleted only if the session is entirely empty if settings.SESSION_COOKIE_NAME in request.COOKIES and empty: response.delete_cookie( settings.SESSION_COOKIE_NAME, path=settings.SESSION_COOKIE_PATH, domain=settings.SESSION_COOKIE_DOMAIN, ) else: if accessed: patch_vary_headers(response, ('Cookie',)) if (modified or settings.SESSION_SAVE_EVERY_REQUEST) and not empty: if request.session.get_expire_at_browser_close(): max_age = None expires = None else: max_age = request.session.get_expiry_age() expires_time = time.time() + max_age expires = cookie_date(expires_time) # Save the session data and refresh the client cookie. # Skip session save for 500 responses, refs #3881. if response.status_code != 500: try: request.session.save() except UpdateError: raise SuspiciousOperation( "The request's session was deleted before the " "request completed. The user may have logged " "out in a concurrent request, for example." ) response.set_cookie( settings.SESSION_COOKIE_NAME, request.session.session_key, max_age=max_age, expires=expires, domain=settings.SESSION_COOKIE_DOMAIN, path=settings.SESSION_COOKIE_PATH, secure=settings.SESSION_COOKIE_SECURE or None, httponly=settings.SESSION_COOKIE_HTTPONLY or None, ) return response

     

  • 相关阅读:
    周总结3
    周总结6
    Java时间日期格式转换
    [专贴]在使用了母版页的内容页后,如何在javascript中调用服务器控件值
    用到函数的题目
    javascript解析dom(2)
    javascript解析dom
    自己的分页
    javascript解析DOM(3)
    转载 ajax XML dataset
  • 原文地址:https://www.cnblogs.com/wangkun122/p/8352768.html
Copyright © 2020-2023  润新知