Flask的session、闪现和g对象

Flask的session、闪现和g对象

一、Session

Flask中的Session机制允许在客户端和服务器之间保持状态信息,这对于构建交互式Web应用至关重要。

1. Session的使用:

在Flask中,Session默认是基于cookie的,它不在服务端存储数据,而是将数据加密后存储在客户端的cookie中。为了扩展性,开发者也可以将Session数据存储到如Redis这样的外部存储系统中。

  • 使用前必须设置secret_key

  • 设置Session值:通过session['key'] = value

  • 获取Session值:使用session.get('key')

  • 删除Session值:通过session.pop('username', None)

  • 清空Session值:通过session.clear()

2. Session的运行机制:

Flask的Session机制与Django等其他框架的Session机制有所不同。

  1. 将数据加密转换成字符串,并以cookie形式返回给前端。
  2. 浏览器在随后的请求中携带这个cookie。
  3. 服务器解析cookie,解密数据,并将其放入session对象中。

3.简单示例

from flask import Flask, session, redirect, url_for,  request

app = Flask(__name__)

# 设置 Flask 应用的 secret_key,这是必须的,用于安全地签名 session cookie
app.secret_key = 'your_secret_key_here'

@app.route('/')
def index():
    # 检查 'username' 是否已经在 session 中
    if 'username' in session:
        username = session['username']
        # 如果用户已登录,显示欢迎信息
        return f'已登录,欢迎您,{username}!'
    return '您未登录!<br><a href="/login">点击这里登录</a>'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        # 假设这里有一些用户验证逻辑
        # 如果验证通过,将用户名存储在 session 中
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    return '''
        <form method="post">
            用户名:<input type="text" name="username">
            <input type="submit" value="登录">
        </form>
    '''

@app.route('/logout')
def logout():
    # 删除 session 中的 'username' 键
    session.pop('username', None)
    return redirect(url_for('index'))

if __name__ == '__main__':
    app.run(debug=True)

4.源码分析

Flask默认使用SecureCookieSessionInterface类来处理Session。

  • 请求到达时

    • 通过open_session方法,解析cookie中的Session数据并解密。

    • def open_session(self, app, request):
       # 打开一个会话并返回安全的Cookie会话或None
      
       # 获取签名序列化器
       s = self.get_signing_serializer(app)
       if s is None:
           return None
      
       # 从请求的cookie中获取值
       val = request.cookies.get(self.get_cookie_name(app))
       if not val:
           return self.session_class()
      
       # 将过期时间转换为秒
       max_age = int(app.permanent_session_lifetime.total_seconds())
       try:
           # 尝试解密数据并返回会话类
           data = s.loads(val, max_age=max_age)
           return self.session_class(data)
       except BadSignature:
           # 数据解密失败时返回会话类
           return self.session_class()
      
  • 请求结束时

    • 通过save_session方法,将session对象中的数据加密后保存到cookie中。

    • def save_session(self, app, session, response):
       name = self.get_cookie_name(app)  # 获取cookie名称
       domain = self.get_cookie_domain(app)  # 获取cookie的域
       path = self.get_cookie_path(app)  # 获取cookie的路径
       secure = self.get_cookie_secure(app)  # 获取cookie的安全属性
       samesite = self.get_cookie_samesite(app)  # 获取cookie的SameSite属性
       httponly = self.get_cookie_httponly(app)  # 获取cookie的httponly属性
      
       # 如果会话被访问,则向响应头部的"Vary"字段添加"Cookie"
       if session.accessed:
           response.vary.add("Cookie")
      
       # 如果会话被修改为空,则移除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
      
       # 如果不应该设置cookie,则返回None
       if not self.should_set_cookie(app, session):
           return
      
       # 获取过期时间,加密会话数据
       expires = self.get_expiration_time(app, session)
       val = self.get_signing_serializer(app).dumps(dict(session))
       # 设置cookie
       response.set_cookie(
           name,
           val,  # type: ignore
           expires=expires,
           httponly=httponly,
           domain=domain,
           path=path,
           secure=secure,
           samesite=samesite,
       )
       response.vary.add("Cookie")
      

二、闪现

1.闪现机制

  1. 存储消息:使用 flash 函数在当前请求的 session 中设置一条消息。可以简单地传递消息文本,也可以指定一个类别(category)来对消息进行分类。
    • 例如:flash('超时错误', category='error')
    • category 是可选参数,可以用于分类消息。
  2. 重定向:通常在设置消息后,会使用 redirect 函数将用户重定向到一个新的页面,这样用户就可以在新的页面中看到消息。
  3. 获取消息:在重定向到的页面上,使用 get_flashed_messages 函数来获取存储的消息。这个函数默认会清除已经获取的消息。
    • 例如:messages = get_flashed_messages(category_filter=['error'])
    • 使用 get_flashed_messages(category_filter=['类别'], with_categories=False) 来获取设置的消息。
      • category_filter 是一个列表,用于指定需要获取哪些类别的消息。
      • with_categories 指定是否返回消息和它们的类别。

2.闪现特点

  • 消息只在下一个请求中可见,之后自动清除,这有助于避免重复显示消息。
  • 可以根据需要为消息设置不同的类别,便于在获取时进行筛选。

3.闪现示例

from flask import Flask, flash, get_flashed_messages, redirect, render_template

app = Flask(__name__)
app.secret_key = 'your_secret_key'  # 必须设置 secret_key 以使用 session

@app.route('/')
def index():
 # 如果发生错误,设置一个错误消息
 flash('超时错误', category='error')
 # 重定向到错误显示页面
 return redirect('/errors')

@app.route('/errors')
def errors():
 # 从 'error' 类别中获取所有闪现的消息
 error_messages = get_flashed_messages(category_filter=['error'])
 # 将消息传递给模板进行显示
 # return render_template('errors.html', error_messages=error_messages)
 return f"错误信息:{error_messages}"
if __name__ == '__main__':
 app.run()

三、g对象

1. 介绍

在 Flask 中,g 对象是一个特殊的对象,用于存储每个请求的全局变量

  • 当请求到达 Flask 应用时,g 对象被创建。

  • g 对象用于存储在请求处理期间需要共享的数据。

  • 它是 global 的缩写,代表请求级别的全局变量。

  • g 对象在请求的整个生命周期内都是可用的,从请求到达开始,直到响应返回结束。

  • 使用 g 对象可以在不同的视图函数、装饰器或中间件之间共享数据。

  • Flask 不建议直接修改 request 对象来存储数据,因为 request 对象应该只包含请求的原始数据。

2.简单示例

from flask import Flask, g, request

app = Flask(__name__)
app.debug = True


@app.before_request
def before_request_func():
 if request.path == '/':  # 在每个请求处理之前,检查请求的路径是否为根路径
     g.path = "g_path"  # 如果是根路径,则将路径信息存储在全局对象g中


@app.route('/')
def index():
 print(g.get('path', 'not found'))  # 如果存在打印信息,否则打印not found
 return 'index'


@app.route('/home')
def home():
 print(g.get('path', 'not found'))  # 如果存在打印信息,否则打印not found
 return 'home'


if __name__ == '__main__':
 app.run()

四、三者之间的异同

在Flask中,session、g对象和闪现(flash)是三种不同的机制,它们用于在请求之间存储和传递数据。

1. Session

  • 定义:Session是服务器端存储,用于跨多个请求保持用户状态。它通常存储在服务器的内存或数据库中,并且可以通过客户端的cookie来访问。
  • 使用场景:适用于需要在用户会话期间保持状态的情况,如用户登录状态、购物车内容等。
  • 特点
    • 数据存储在服务器端,客户端通过cookie访问。
    • 可以存储任意类型的数据。
    • 需要设置秘钥(SECRET_KEY)来保证安全性。

2. g对象

  • 定义:g是一个全局对象,用于在应用的请求和上下文中存储数据。g对象的数据只会在当前请求的生命周期内有效。
  • 使用场景:适用于在同一请求中不同视图函数之间共享数据。
  • 特点
    • 数据仅在当前请求有效,请求结束后数据会被销毁。
    • 可以通过g对象存储临时数据。
    • 通常用于避免在视图函数中重复计算或获取数据。

3.闪现(Flash)

  • 定义:闪现是一种特殊的消息传递机制,用于在请求之间传递一次性消息。闪现的消息在下一次请求时自动清除。
  • 使用场景:适用于需要向用户显示一次性反馈信息的情况,如表单提交后的成功或错误消息。
  • 特点
    • 消息在下一次请求时自动清除,只显示一次。
    • 通常用于用户交互反馈,如“注册成功”、“登录失败”等。
    • 可以通过flash()函数来设置消息,并在模板中使用get_flashed_messages()来显示。
    • 需要设置秘钥(SECRET_KEY)来保证安全性。

4.异同点:

  • 相同点
    • 都是Flask框架提供的数据存储和传递机制。
    • 都可以在请求之间传递信息。
  • 不同点
    • 生命周期:session跨多个请求有效,g对象仅在当前请求有效,闪现在下一次请求后自动清除。
    • 存储位置:session存储在服务器端,g对象和闪现的数据存储在服务器内存中。
    • 使用目的:session用于保持用户状态,g对象用于请求内数据共享,闪现用于一次性用户反馈。
    • 安全性:session需要设置秘钥来保证安全,g对象和闪现通常用于传递非敏感信息。

  • 24
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值