session源码、闪现、请求扩展
session源码
''' 1 app.session_interface 默认是某个类的对象,以后全局对象 session,就是SecureCookieSessionInterface()的对象 2 请求来了,会执行这个对象的: open_session方法 3 请求走了,会执行这个对象的:save_session方法 4 找出上面讲的--》读源码--》 app.run()---->run_simple(地址, 端口, self可调用对象)--->self 是谁?就是 app 请求来了,就会执行 self可调用对象()--->app()---->对象加括号---》触发---》类的__call__ 请求来了,就会执行flask类的 __call__--->self.wsgi_app(environ, start_response) def wsgi_app(self, environ: dict, start_response: t.Callable) -> t.Any: ctx = self.request_context(environ) try: try: ctx.push() response = self.full_dispatch_request() except Exception as e: error = e response = self.handle_exception(e) except: # noqa: B001 error = sys.exc_info()[1] raise return response(environ, start_response) finally: if "werkzeug.debug.preserve_context" in environ: environ["werkzeug.debug.preserve_context"](_cv_app.get()) environ["werkzeug.debug.preserve_context"](_cv_request.get()) if error is not None and self.should_ignore_error(error): error = None ctx.pop(error) # 5 ctx.push()--->有如下代码 if self.session is None: # 请求刚来,是空的 #session_interface 就是SecureCookieSessionInterface类的对象 self.session = session_interface.open_session(self.app, self.request) if self.session is None: self.session = session_interface.make_null_session(self.app) #6 SecureCookieSessionInterface类的open_session from flask.sessions import SecureCookieSessionInterface open_session步骤: 1 会去cookie中取出session对应的 三段式的字符串 2 解密,校验签名---》把这个数据--》放到 session对象中 save_session步骤: 1 从session取出数据 2 加密,签名---放到cookie中 3 返回给前端 '''
save_session
''' 1 视图函数中,咱们 session[name]=lqz 2 请求走了,会触发save_session 3 触发save_session时: 把session中的数据,加密签名得到三段字符串 放到cookie中,放到了浏览器中 ''' def save_session( self, app: Flask, session: SessionMixin, response: Response ) -> None: name = self.get_cookie_name(app) domain = self.get_cookie_domain(app) path = self.get_cookie_path(app) secure = self.get_cookie_secure(app) samesite = self.get_cookie_samesite(app) httponly = self.get_cookie_httponly(app) # Add a "Vary: Cookie" header if the session was accessed at all. if session.accessed: response.vary.add("Cookie") # If the session is modified to be empty, remove the cookie. # If the session is empty, return without setting the cookie. if not session: if session.modified: response.delete_cookie( name, domain=domain, path=path, secure=secure, samesite=samesite, httponly=httponly, ) response.vary.add("Cookie") return if not self.should_set_cookie(app, session): return expires = self.get_expiration_time(app, session) # 加密,签名---放到cookie中 val = self.get_signing_serializer(app).dumps(dict(session)) # type: ignore response.set_cookie( name, val, # type: ignore expires=expires, httponly=httponly, domain=domain, path=path, secure=secure, samesite=samesite, ) response.vary.add("Cookie")
open_session
''' 1 请求来了,request中带着cookie(也有可能没有) 2 根据 session这个key,取出value,如果有,就是 我们当时生成的三段 3 字典=s.loads(value) 把内容验签,解密出来,转成了字典 4 把这个字典转到 session对象中 5 以后视图函数中 session[name] 就能取到当时你放的name ''' def open_session(self, app: Flask, request: Request) -> SecureCookieSession | None: s = self.get_signing_serializer(app) if s is None: return None # val 就是那三段 val = request.cookies.get(self.get_cookie_name(app)) if not val: # 如果没有带cookie,造个空session,返回 return self.session_class() max_age = int(app.permanent_session_lifetime.total_seconds()) try: data = s.loads(val, max_age=max_age) # 解密,校验签名---》把这个数据--》放到 session对象中 return self.session_class(data) except BadSignature: return self.session_class()
django session的控制
from django.contrib.sessions.middleware import SessionMiddleware
闪现
# flash 翻译过来的 # 假设在a页面操作出错,跳转到b页面,在b页面显示a页面的错误信息 # 以后遇到,在当次请求有数据要存,下次请求还能取出来,就可以使用闪现 ### 设置闪现 # 1 普通使用 :通过闪现---》放进去,取一次,就没了 # flash(s) # 放到闪现中了,加密放到了cookie总 # 2 分类,以分类放入 flash(s, category='xxx') flash('xxx', category='yyy') ### 取闪现 # 1 普通取,全取出来 从闪现中取出来 # err = get_flashed_messages()[0] # 2 根据分类取 err = get_flashed_messages(category_filter=['xxx'])[0] # 总结: 1 设置flash,可以按分类设置 2 去flash,在当前请求中,可以取出多次,都是在的 3 一旦有请求取出,再去别的的请求中取,就没了,无论有没有分类,都没了
请求扩展
# django 中中间件,对所有请求拦截 # flask中使用请求扩展实现 django flask -process_request----》before_request -process_response--->after_request # 就是django中间件 请求头中判断有没有user-agent 做反扒 响应头中加入 跨域的
from flask import Flask, session, redirect, request, flash, get_flashed_messages,make_response app = Flask(__name__) app.secret_key = 'asdfasdf' app.debug = True @app.before_request def before(): # 做统一处理,处理校验失败,不让他继续往后走了 ''' return None---->继续走下一个请求扩展 return 新手四件套 ''' print('来了') @app.before_request def before2(): # 做统一处理,处理校验失败,不让他继续往后走了 ''' return None---->继续走下一个请求扩展 return 新手四件套 ''' print('来了222') # return '不行了' @app.after_request def after(response): print('走了') # return response return make_response('你看到我了') @app.route('/') def home(): print('home') return 'home' @app.route('/order') def order(): return 'order' if __name__ == '__main__': app.run()