flask 状态保持session和上下文session的区别

问题场景:

  在falsk项目中导入了两个session:

    首先,配置文件config.py文件中 有个 flask_session扩展导入了Session  ( from flask_session import Session );

  然后,在login.py文件的登录接口中  有从flask导入了session   (from flask import session);

先阐述一下状态保持的概念以及浏览器服务器如何实现状态保持:

  1 状态保持:
    有时需要保持下来用户浏览的状态,比如用户是否登录过,浏览过哪些商品等,
    实现状态保持主要有两种方式:使用Cookie在客户端存储信息,使用Session在服务器端存储信息

    1.1.Cookie:
    ▪Cookie是由服务器端生成,发送给客户端浏览器,浏览器会将Cookie的key/value保存,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)。

    ▪应用:最典型的应用是判定注册用户是否已经登录网站,用户可能会得到提示,是否在下一次进入此网站时保留用户信息以便简化登录手续,这些都是Cookie的功用。
    ▪提示:Cookie基于域名安全,不同域名的Cookie是不能互相访问的
如:访问jingdong.com时向浏览器中写了Cookie信息,使用同一浏览器访问baidu.com时,无法访问到jingdong.com写的Cookie信息,浏览器的同源策略。

    1.2.session:
对于敏感、重要的信息,建议要存储在服务器端,不能存储在浏览器中,如用户名、余额、等级、验证码等信息,在服务器端进行状态保持的方案就是Session,Session依赖于Cookie

  2、区别:

    2.1  当然,在flask项目中也要实现状态保持,把Cookie存储在浏览器,session存储到服务器,但是当我们的用户量较大时,各种状态保持信息(用户信息,浏览历史信息等)都放到session中,就会大大的增加服务器的负荷,为了减轻服务器的压力,我们就把session放到redis数据库中,另外,redis数据库读取数据也是更快的,这个功能的实现靠的就是flask-session扩展中的Session;  即session是基于浏览器的cookie进行保存在服务器上的,flask_session可以把session的值存储在redis数据库中。这个session无论用户登录还是退出,只要不过期,就一直存在,与框架无关,与语言无关,便于用户在浏览器端再次便捷登录。

    2.2  from flask import session  这个sesssion是flask框架内置的请求上下文对象,用来操作记录http请求的数据或session信息,在请求过程中存在,请求结束后就被销毁;比如只有登录的用户并且发送http请求时,它才被唤醒存储内容,用户退出时,它又被销毁;在本flask项目的应用场景:

      (1) 在登录接口,用户用过mobile 和password验证后(用户存在且密码正确),我们就通过mobile查询出该用户对象user, 再把该登录用户的name,user_id, mobile 保存到上下文session中,方便其他模块接口的调用当前登陆的用户信息。

      (2) 在登录接口实现登陆以后,我们如何在其他接口判断用户是否登录呢?很简单,我们只需用user_id = session.get("user_id"),如果user_id存在,就说明用户已经通过了登录接口的验证和session信息的保存。因为很多接口都要判断登录状态,我们通常把这个功能放到装饰其中(即重写flask_login的login_required方法),方便各接口调用

    在utils/common.py文件中重写login_required方法:

    

 1 def login_required(func):
 2     '''检查用户的登录状态'''
 3     @wraps(func)
 4     def wrapper(*args, **kwargs):
 5         # 核心逻辑 获取session的id
 6         user_id = session.get('user_id')
 7         if user_id is not None:
 8             # 表示用户已经登录 
 9             # 后面的接口仍需要user_id数据,来获取当前登陆的用户
10             # 为了方便,可以使用g变量来记录,避免多次访问保存session的redis服务器或项目服务器(根据session存放的位置)
11             g.user_id = user_id
12             return func(*args, **kwargs)
13         else:
14             retrun jsonify(error='4005', errmsg='用户未登录')
15      return wrapper

    在其他接口的应用:(判断是否登录和获取登录用户id,这也是login_required的两个功能, 不重写的话只有判断功能)

 1 from ihome.utils.common import login_required
 2 
 3 @api.route("/sessions", methods=["DELETE"])
 4 @login_required    # 验证登录装饰器
 5 def logout():
 6     """登出"""
 7     # 清除session数据, csrf_token需要保留.
 8     csrf_token = session['csrf_token']
 9     session.clear()
10     session['csrf_token'] = csrf_token
11 
12     # 删除session的方式:3种
13     # 1.session.pop()  2. 和Django所学相同  3. session.clear()全部删除
14 
15     return jsonify(errno=RET.OK, errmsg="OK")
原文地址:https://www.cnblogs.com/We612/p/10400745.html