flask session组件的使用示例

一、简介

flask中session组件可分为内置的session组件还有第三方flask-
session组件,内置的session组件功能单一,而第三方的flask-
sessoin可支持redis、memcached、文件等进行session的存储。以下将介绍内置session以及第三方session组件的使用方法以及处理机制。

二、内置session处理机制

Cookie与Session

Cookie:

Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。

Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容

Session:

Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了,实质上session就是保存在服务器端的键值对。

如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。

第一次请求,session的创建过程

flask上下文
中介绍了,请求到flask框架会执行wsgi_app方法:


    def wsgi_app(self, environ, start_response):
     ctx = self.request_context(environ) #实例化生成RequestContext对象
     error = None 
     try:
      try:
       ctx.push() #push上下文到LocalStack中
       response = self.full_dispatch_request() #执行视图函数过程
      except Exception as e:
       error = e
       response = self.handle_exception(e) #处理异常
      except:
       error = sys.exc_info()[1]
       raise
      return response(environ, start_response)
     finally:
      if self.should_ignore_error(error):
       error = None
      ctx.auto_pop(error)  # 删除LocalStack中的数据
    

在改方法中会生成一个ctx也就是RequestContext对象:


    class RequestContext(object):
     def __init__(self, app, environ, request=None):
      self.app = app # app对象
      if request is None:
       request = app.request_class(environ) 
      self.request = request # 封装request
      self.url_adapter = app.create_url_adapter(self.request)
      self.flashes = None
      self.session = None #一开始的session
    

在这个对象中封装了session,最初为None。接着在wsgi_app中执行ctx.push:


    def push(self):
      app_ctx = _app_ctx_stack.top # 获取app上下文
      if app_ctx is None or app_ctx.app != self.app:
       app_ctx = self.app.app_context() #将app上下文push到app_ctx对于的LocalStack中
       app_ctx.push()
       self._implicit_app_ctx_stack.append(app_ctx)
      else:
       self._implicit_app_ctx_stack.append(None)
      if hasattr(sys, 'exc_clear'):
       sys.exc_clear()
      _request_ctx_stack.push(self)
      if self.session is None: # 判断session是否为None,一开始为None
       session_interface = self.app.session_interface # 获取操作session的对象
       self.session = session_interface.open_session( #调用open_session 创建session
        self.app, self.request
       )
       if self.session is None:
        self.session = session_interface.make_null_session(self.app)
    

这里我们主要关注session,前面的代码在上下文中已经进行了相关说明,这里有个判断session是否为None,刚开始RequestContext中的session为None,所以条件成立,此时执行以下语句:


    session_interface = self.app.session_interface
    self.session = session_interface.open_session(
        self.app, self.request
       )
    if self.session is None:
     self.session = session_interface.make_null_session(self.app)
    

首先来看session_interface =
self.app.session_interface,self.app.session_interface就是app中的session_interface属性:


    session_interface = SecureCookieSessionInterface()
    

默认是一个SecureCookieSessionInterface()对象,该对象的内部主要实现了open_session和save_session用于使用和保存session。接着self.session被重新赋值为session_interface.open_session(self.app,
self.request)方法返回的值,以下为open_session源码:


    def open_session(self, app, request):
     s = self.get_signing_serializer(app) #根据app.secret_key获取签名算法
     if s is None:
      return None
     # 根据配置中的session_cookie_name获取session对于的值
     val = request.cookies.get(app.session_cookie_name) #如果request.cookies为空,val为空
     if not val:
      return self.session_class()
     max_age = total_seconds(app.permanent_session_lifetime)    
     try:
      data = s.loads(val, max_age=max_age)
      return self.session_class(data)
     except BadSignature:
      return self.session_class()
    

该方法返回self.session_class(),当请求第一次来时,request.cookies为None,所以val也为None,返回self.session_class(),而session_class又是SecureCookieSession:


    session_class = SecureCookieSession

所以我们继续看SecureCookieSession:


    class SecureCookieSession(CallbackDict, SessionMixin):
     accessed = False
    
     def __init__(self, initial=None):
      def on_update(self):
       self.modified = True
       self.accessed = True
    
      super(SecureCookieSession, self).__init__(initial, on_update)
    
     def __getitem__(self, key):
      self.accessed = True
      return super(SecureCookieSession, self).__getitem__(key)
    
     def get(self, key, default=None):
      self.accessed = True
      return super(SecureCookieSession, self).get(key, default)
    
     def setdefault(self, key, default=None):
      self.accessed = True
      return super(SecureCookieSession, self)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值