关于 flask_session 在登录时设置后,再其他接口获取时为None的问题
flask本身的session对于生产来讲可能并不能满足我们,我们需要使用三方插件来满足我们的生产环境。
一般情况下,session对应的存储值我们需要持久化到数据库中,所以我们的session将会启用flask三方插件:flask_session
配置flask_session 由于每个项目的不同我的配置未必符合你的项目,你可以直接查看flask_session的官方文档: Usage - Flask-Session 0.8.0 documentation
在settings里面的配置
SESSION_TYPE = "redis" SESSION_REDIS = Redis( host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD, db=REDIS_RESULTS_DB ) # type: ignore PERMANENT_SESSION_LIFETIME = dt.timedelta(minutes=5) SESSION_COOKIE_DOMAIN = "*"
然后创建工厂函数等,以下是项目配置,我们可能并不相同
from flask_session import Session session = Session()
from xxx.extensions import session session.init_app(self.flask_app)
创建好后,我们在项目上使用一下
class Captcha(MethodView): def get(self): session["b64_str"] = “text” return json_response(data=b64_str) class Captcha111(MethodView): def get(self): text = session.get("b64_str") print(text) return json_response(data=text)
当我们在调用captcha111的时候,你会发现session所get出来的数据是None。
这不符合我们对session的期望,这时我们需要知道为什么会发生这种事。
解决问题的思路。
首先你需要知道,会不会是我们的redis数据库的问题,我们先验证数据是否是没问题的。
我们把settings里面的数据库连接中,密码修改为错误密码,当我们调用captch路由时,会抛出redis连接异常的错误,说明我们的redis连接是没问题的,一般情况下,里面所存储的数据就也是没问题的,我们应该这种自信,断定redis是没问题的。
既然redis是没问题的,那就看在第二个路由里面获取时,走没走redis数据库,初步考虑应该是没有的,不然不会取不出来,我们可以采取刚才的方式,将数据库的密码修改为错误,然后在调用获取的方法,发现并未出现数据库连接报错,可见,当前的session在获取数据时,并未连接数据库,这就可以侧面印证,在某一时刻,我们的session和上次的session并非是同一个session,哪怕这个session的id是相同的id。
这时,我们就需要知道flask_session的运行原理,否则我们无法得知它在哪个环节被限制住了:flask学习笔记--flask内置session处理机制_flask session httponly-CSDN博客
当我们得知它会在
这里进行相应的拦截时,我们可以考虑是不是因为我们使用postman二次访问未携带相应的cookie导致的。
理论成立,实践动手:
我们使用浏览器访问后,取得cookie:
然后取出cookie后,我们是用postman发起访问:
果然,data的数据出现,说明我们的想法是没问题的。
那么问题回到刚才,我们此时的session.get会访问redis数据库吗?
答案是:会的。随后我便验证了,当密码不正确时,代码执行到此处时会抛出数据库未连接的异常信息。
最后,当你想让它出现在cookie,以便前端直接访问时:
你可以这样写:
class Captcha(MethodView): __doc__ = """获取图片验证码""" def get(self): from flask import Response b64_str, text = generate_captcha() session["b64_str"] = text response = json_response(code=CODE.OK.code, data=b64_str) response.set_cookie("session", session.sid) return response