flask基础之session原理详解(十)

flask_session是flask框架实现session功能的一个插件,用来替代flask自带的session实现机制,flask默认的session信息保存在cookie中,不够安全和灵活。

flask的session机制

session是用来干什么的呢?由于http协议是一个无状态的协议,也就是说同一个用户第一次请求和第二次请求是完全没有关系的,但是现在的网站基本上有登录使用的功能,这就要求必须实现有状态,而session机制实现的就是这个功能。

实现的原理:

用户第一次请求后,将产生的状态信息保存在session中,这时可以把session当做一个容器,它保存了正在使用的所有用户的状态信息;这段状态信息分配了一个唯一的标识符用来标识用户的身份,将其保存在响应对象的cookie中;当第二次请求时,解析cookie中的标识符,拿到标识符后去session找到对应的用户的信息。

简单使用 from flask import Flask,session app = Flask(__name__) @app.route('/test1/') def test(): session.setdefault('name', 'xiaoming') return 'OK' if __name__ == '__main__': app.run(host='127.0.0.1', port=80, debug=True)

在flask中,如果我们想要获取session信息,直接通过flask的session获取就可以了,这是因为session是一个代理对象,代理当前请求上下文的session属性。

session源码分析

依据上述session的原理,来分析一下flask框架的session机制实现的过程。

Flask对象使用open_session方法和save_session方法打开和保存会话信息,请求在创建请求上下文后会调用open_session方法获取用户的信息,在执行完处理逻辑后会调用save_session方法保存用户的信息。

open_session和save_session

def open_session(self, request): # 调用了app的session_interface对象的方法 return self.session_interface.open_session(self, request) def save_session(self, session, response): return self.session_interface.save_session(self, session, response)

app对象默认的session_interface = SecureCookieSessionInterface(),SecureCookieSessionInterface重写了SessionInterface对象的open_session方法和save_session方法。

class SecureCookieSessionInterface(SessionInterface): pass def open_session(self, app, request): # 检测是否设置了secret_key参数,返回一个签名对象 s = self.get_signing_serializer(app) if s is None: return None # 去cookie中获取session信息 val = request.cookies.get(app.session_cookie_name) # 如果是第一次请求,返回一个空的SecureCookieSession对象,会被交给请求上下文的session属性管理 if not val: return self.session_class() # 获取session的失效时间 max_age = total_seconds(app.permanent_session_lifetime) try: # 对session信息进行解码得到用户信息 data = s.loads(val, max_age=max_age) # 返回有用户信息的session对象 return self.session_class(data) except BadSignature: return self.session_class() def save_session(self, app, session, response): # 获取cookie设置的域 domain = self.get_cookie_domain(app) # 获取cookie设置的路径 path = self.get_cookie_path(app) ... # 检测SESSION_REFRESH_EACH_REQUEST参数配置 if not self.should_set_cookie(app, session): return # 返回SESSION_COOKIE_HTTPONLY参数配置 httponly = self.get_cookie_httponly(app) # 返回SESSION_COOKIE_SECURE参数配置 secure = self.get_cookie_secure(app) # 返回失效的时间点 expires = self.get_expiration_time(app, session) #将用户的数据加密 val = self.get_signing_serializer(app).dumps(dict(session)) # 设置cookie response.set_cookie(app.session_cookie_name, val, expires=expires, httponly=httponly, domain=domain, path=path, secure=secure)

请求上下文RequestContext的session属性是一个SecureCookieSession对象,可以将其看做一个字典;

相关的配置参数 SESSION_COOKIE_NAME:设置返回给客户端的cookie的名称,默认是“session”;放置在response的头部; SESSION_COOKIE_DOMAIN:设置会话的域,默认是当前的服务器,因为Session是一个全局的变量,可能应用在多个app中; SESSION_COOKIE_PATH:设置会话的路径,即哪些路由下应该设置cookie,如果不设置,那么默认为‘/’,所有的路由都会设置cookie;这个参数和SESSION_COOKIE_DOMAIN是互斥的 SERVER_NAME:设置服务器的名字,一般不用; SESSION_COOKIE_SECURE:如果 cookie 标记为“ secure ”,那么浏览器只会使用基于 HTTPS 的请求发 送 cookie,应用必须使用 HTTPS 服务来启用本变量,默认False APPLICATION_ROOT:设置应用的根路径; SESSION_REFRESH_EACH_REQUEST:是否应该为每一个请求设置cookie,默认为True,如果为False则必须显性调用set_cookie函数; SESSION_COOKIE_HTTPONLY:cookie应该和httponly标志一起设置,默认为True,这个一般采用默认。 PERMANENT_SESSION_LIFETIME:设置session的有效期,即cookie的失效时间,单位是s。这个参数很重要,因为默认会话是永久性的。 SESSION_COOKIE_HTTPONLY:默认为true,表示允许js脚本访问cookie; 小结

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfzpw.html