• 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")
  • 相关阅读:
    Java设计模式--Java Builder模式
    Android网络开发之OkHttp--基本用法实例化各个对象
    Android网络开发之OkHttp--基本用法POST
    Android网络开发之OkHttp--基本用法GET
    Eclipse开发工具的使用之-使用Eclipse的Debug调试Android程序
    Android网络开发之Volley--Volley自定义Request
    弹出软键盘时,不把activity整体往上移,只移动部分
    圆角背景实现,如实现圆角按钮;用xml文件画圆
    在java代码中设置TextView文本内容可滚动
    Android模拟HOME键的效果
  • 原文地址:https://www.cnblogs.com/We612/p/10400745.html
Copyright © 2020-2023  润新知