zoukankan      html  css  js  c++  java
  • 【10】Flask 高级摘要

    01-cookie

    1.1 什么是cookie?

    cookie技术产生源于HTTP协议在互联网上的急速发展,在浏览器发展初期,为了适应用户的需求,技术上推出了各种保持web浏览状态的手段,为什么要保持web浏览器的状态呢?

    一般web通信是基于HTTP的,HTTP是无状态的协议,也就是说,在一次请求响应结束后,服务器不会留下任何有关于对方状态信息,所以需要保持web浏览器的状态。

    比如:对于有些web应用来说,客户端的某些信息必须被记住。比如用户登录过后跳转页面依然要保持登录的状态,进行其他的业务访问,而当这个登录过的用户再次访问web服务器的时候,web服务器并不知道这个用户已经登录过了,所以无法进行其他需要权限的业务访问。所以cookie技术的出现就是为了解决这个问题。

    cookie的具体实现过程:当一个用户访问web服务器后,web服务器会获取用户的状态并且返回一些数据(cookie)给浏览器,浏览器会自动储存这些数据(cookie),当用户再次访问web服务器,浏览器会把cookie放到请求报文中发送给web服务器,web服务器就会获取到了用户的状态。基于这次用户的状态方便用户进行其他业务的访问,并且web服务器可以设置浏览器保存cookie的时间,cookie是有域名的概念,只有访问同一个域名的时候才会把之前相同域名返回的cookie携带给该web服务器。

    附注:1993年,网景公司雇员Lou Montulli为了提升用户体验,进一步实现了个人化网络。发明了今天广泛使用的Cookie

    关键词

    • web通讯一般基于HTTP协议,HTTP是无状态协议。
    • Cookie技术是用来保持web访问状态,Cookie技术通过在请求和响应报文中添加Cookie数据来保存客户端的状态信息
    • 服务器可以设置cookie的有效期,浏览器会自动清除过期的cookie
    • cookie有域名的概念,只有访问同一个域名,才会把之前相同域名返回的cookie携带给该服务器。

    1.2 如何在flask中使用cookie?

    1.2.1 设置cookie

    设置cookie的时候是由我们web服务器设置,也就是在Flask项目中生成cookie,经由响应报文返回给浏览器保存cookie,下次浏览器再访问web服务器的时会在请求报文中把cookie携带过来,所以cookie产生的起点是在web服务器中,也就是我们的Flask项目中。

    在Flask中如果想要在响应中添加一个cookie,最方便的做法是使用内置的Response类提供的set_cookie()方法。

    表-2.2.1.1 set_cookie()方法的参数

    属性 说明
    key cookie的键(名称)
    value cookie的值
    max_age cookie被保存的时间数,单位为秒。
    expires 具体的过期时间,一个datetime对象或UNIX时间戳
    path 限制cookie只在给定的路径可用,默认为整个域名下路径都可用
    domain 设置cookie可用的域名,默认是当前域名,子域名需要利用通配符domain=.当前域名
    secure 如果设为True,只有通过HTTPS才可以用
    httponly 如果设为True,进制客户端JavaScript获取cookie

    1.2.1.2 实例:设置cookie

    项目目录

    │  app.py
    │
    ├─static	# 文件夹
    └─templates # 文件夹
    

    app.py

    from flask import Flask, Response
    
    app = Flask(__name__)
    
    
    @app.route('/')
    def hello_world():
        resp = Response('设置cookie给浏览器')
        resp.set_cookie('user_name', 'mark')
    
        return resp
    
    if __name__ == '__main__':
        app.run(port=5001)
    

    解读 app.py

    (1) 首先导入Flask内置的Response类,用于在响应报文中设置cookie

    from flask import Flask,request, Response
    

    (2) 在视图函数实例化Response类并传入返回的内容,Response类实例化出的对象调用set_cookie()方 法,set_cookie内的第一个参数是设置cookie的key,第二个参数是用来设置cookie的value,然后返回该对象,就会携带着设置好的cookie返回给浏览器保存。

    @app.route('/')
    def hello_world():
        resp = Response('设置cookie给浏览器')
        resp.set_cookie('user_name', 'mark')
    
        return resp
    

    1.2.1.3 在浏览器中查看cookie的三种方式(以Chrome浏览器为例)

    基于2.2.1.2实例

    第一种: 右键检查----->Network---->找到访问的域名---->找到Response Headers---->Set-Cookie

    第二种:点击url输入框左边的信息icon,然后找到响应的域名,展开查看cookie。

    第三种:设置---->高级---->内容设置---->Cookie---->查看所有cookie设置----->根据域名搜索对应的cookie信息

    1.2.2 设置cookie的有效期

    注意:Flask服务器默认设置cookie有效期为关闭浏览器后cookie失效

    1.2.2.1 基于max_age参数设置cookie有效期

    再设置cookie的调用set_cookie()时候传入关键字实参 max_age= 值,这个代表多少秒后过期。

    注意:max_age参数设置过期时间不兼容IE8一下的浏览器

    ...
    @app.route('/')
    def hello_world():
        resp = Response('设置cookie给浏览器')
        resp.set_cookie('user_name', 'mark',max_age=60)
        
        return resp
    ...
    

    1.2.2.2 基于expires参数设置cookie有效期

    再设置cookie的调用set_cookie()时候传入关键字实参 expires= 值,这个代具体的过期时间,一个datetime对象或UNIX时间戳。

    使用expires参数,就必须会用格林尼治时间(也就是相对北京时间少8个小时,因为浏览器会默认把服务器传来的时间值当做标准格林尼治时间,并根据当地的时区做调整

    @app.route('/expires_demo/')
    def expires_demo():
        resp = Response('设置cookie给浏览器, cookie设置过期时间为一个月后')
        expires = datetime.now()+timedelta(days=30, hours=16)
        resp.set_cookie('user_name', 'mark', expires=expires)
        return resp
    

    1.2.3 在Flask中查询cookie

    基于2.2.1.2 实例

    查询cookie 是通过请求对象的cookies属性读取,读取的过程是使用设置cookie时的key来读取到设置cookievalue

    ...
    @app.route('/get_cookie/')
    def get_cookie():
        user_name = request.cookies.get('user_name')
        if user_name == 'mark':
            return '{}的信息'.format(user_name)
    
        return 'cookie验证失败'
    ...
    

    1.2.4删除cookie

    基于2.2.1.2实例

    删除cookie是通过Flask内置的Response类实例化出的对象调用delete_cookie('key'),删除的过程是使用设置cookie时的key来删除cookie信息。

    @app.route('/del/')
    def del_cookie():
        resp = Response('删除cookie')
        resp.delete_cookie('user_name')
        return resp
    

    02-session

    2.1 什么是session?

    session的基本概念:session又称之为安全的cookie,session是一个思路、是一个概念、一个服务器存储授权信息的解决方案,不同的服务器,不同的框架,不同的语言有不同的实现,session的目的和cookie完全一致,cookie在客户端和服务端处理的非常粗糙,cookie在浏览器保存的时候以及传输的过程均使用明文,导致了很多安全隐患问题,session的出现就是为了解决cookie存储数据不安全的问题。

    注意:session是一个思路一个概念,session的实现是基于cookie的,session并不像cookie是一项真实存在的技术,可以简单的理解为把粗糙的cookie在服务端通过加密,永久化等方式提高cookie的安全级别。

    2.2 实现session的两种思路

    第一种

    1. 客户端携带用户信息请求服务端验证。
    2. 服务端验证成功后生成随机的session_id与用户信息建立映射后存储到数据库中(注意:数据库可以是任意永久化保存数据的机制,如redis、memcached、mysql、甚至是文件等等)。
    3. 服务端把刚刚生成的session_id作为cookie信息返回给客户端。
    4. 客户端收到以session_id为内容的cookie信息保存到本地。
    5. 客户端再次请求的时候会携带以session_id为内容的cookie去访问服务端,服务端取出session_id去数据库校验得到用户信息。

    第二种

    1. 客户端携带用户信息请求服务端验证。
    2. 服务端收到用户信息验证成功后,服务端再把用户信息经过严格的加密加盐生成session信息。并且把刚刚生成的session信息作为cookie的内容返回给客户端。
    3. 客户端收到以session信息为内容的cookie保存到本地。
    4. 客户端再次请求的时候会携带以session信息为内容的cookie去访问服务端,服务端取出session信息经过解密得到用户的信息。

    注意:flask使用的就是第二种思路,利用加密解密的方式实现session,实现安全的cookie,服务端并不会做永久化的储存。

    2.3 如何在flask中实现session?

    2.3.1 设置session

    Flask提供了session对象用来将cookie加密储存,session通过秘钥对数据进行签名以加密数据。

    from flask import Flask, session
    import os
    
    app = Flask(__name__)
    app.config['SECRET_KEY'] = os.urandom(24) # 配置session使用的秘钥
    
    @app.route('/')
    def set_session_info():
        session['username'] = 'mark' # 使用用户信息配置sesion信息作为cookie,并添加到响应体中
        
        return '设置session信息'
    

    解读

    通过app对象 通过SECRET_KEY配置session使用的加密秘钥

    app.config['SECRET_KEY'] = os.urandom(24) # 配置session使用的秘钥
    

    session对象像可以字典一样操作,内部是把字典的信息进行加密操作然后添加到相应体中作为cookie,响应的时候会自动返回给浏览器。

     session['username'] = 'mark'
     session['userphone'] = '123456'  # 可以指定多条session信息,统一放到响应的cookie中返回给浏览器
    

    2.3.2 设置session有效期

    后端Flask跟浏览器交互默认情况下,session cookie会在用户关闭浏览器时清除。通过将session.permanent属性设为True可以将session的有效期延长为31天,也可以通过操作app的配置PERMANENT_SESSION_LIFETIME来设置session过期时间。

    一般配合PERMANENT_SESSION_LIFETIM 设置有效实现

    案例 3.3.2.1:开启指定session过期时间模式

    from flask import Flask, session
    import os
    
    app = Flask(__name__)
    app.config['SECRET_KEY'] = os.urandom(24)
    
    
    @app.route('/')
    def set_session_info():
        session['username'] = 'mark'
        session['userphone'] = '123456'
        session.permanent = True # 开启设置有效期,默认为31天后过期
        return 'Hello World!'
    ...
    

    案例 3.3.2.1:开启session指定过期时间模式后指定具体的过期时间

    基于案例3.3.2.1,通过设置PERMANENT_SESSION_LIFETIME指定具体的过期时间,session.permanent属性设为True,才会生效

    from datetime import timedelta
    app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=1) # 设置为1小时候过期
    

    2.3.3 获取session

    在Flask中获取设置的session信息通过session对象获取,session对象是继承了字典类,所以获取的时候是字典的取值方式。其内部会把浏览器传过来的session信息解密。

    @app.route('/get_session/')
    def get_session():
        username = session.get('username')
        userphone = session.get('userphone')
        if username or userphone:
            return "{},{}".format(username, userphone)
        return "session为空"
    

    2.3.4 删除session

    session对象调用pop()可以根据具体的session的key清除掉指定的session信息。

    session对象调用clear()可以清除此次请求的浏览器关于本域名的所有session信息

    @app.route('/del_session/')
    def del_session():
        session.pop('username')
        # session.clear()
        return '删除成功'
    

    3.1 flask模板上下文处理器

    app对象调用context_processor作为模板上下文处理器,视图函数在每一次调用render_template('')的时候都会为模板传入@app.context_processor装饰器所装饰函数的返回值,该返回值作为模板变量,但是返回值一定要为字典,如果不想返回任何值,可以返回空字典,否则会报错,返回值可以设置为模板经常要使用的变量,减少了代码的冗余,提高了代码的可维护性。

    实例 4.1

    ...
    
    @app.route('/')
    def hello_world():
        context_dict = {
            "username": "马克"
        }
        
        return render_template('index.html', **context_dict)
    
    
    @app.route('/detail/')
    def detail():
        context_dict = {
            "username": "马克"
        }
        
        return render_template('detail.html', **context_dict)
    
    
    ...
    

    实例4.2

    实例4.2 利用模板上下文处理器避免了一些代码的冗余,利用该处理器,可以为视图函数每一次返回模板的时候传入设置好的变量,实例4.2实现的效果同实例4.1完全一致。

    ...
    
    @app.route('/')
    def hello_world():
        return render_template('index.html')
    
    @app.route('/detail/')
    def detail():
        return render_template('detail.html')
    
    @app.context_processor
    def context_processor():
        return {"username":"马克"}
    
    ...
    

    适用场景:比如登录网站后用户信息始终显示在页面的右上角,我们可以利用模板上下文处理器,做到每次返回模板的时候都为其传入用户信息,减少了代码的冗余,提高了代码的可维护性。

  • 相关阅读:
    Android中Context具体解释 ---- 你所不知道的Context
    JDK6、Oracle11g、Weblogic10 For Linux64Bit安装部署说明
    matplotlib 可视化 —— 定制 matplotlib
    matplotlib 可视化 —— 移动坐标轴(中心位置)
    matplotlib 可视化 —— 移动坐标轴(中心位置)
    matplotlib 可视化 —— 定制画布风格 Customizing plots with style sheets(plt.style)
    matplotlib 可视化 —— 定制画布风格 Customizing plots with style sheets(plt.style)
    指数函数的研究
    指数函数的研究
    指数分布的研究
  • 原文地址:https://www.cnblogs.com/remixnameless/p/13290865.html
Copyright © 2011-2022 走看看