flask session

 

默认情况下 Flask 创建的类对session 信息处理的方式和 对应的类

 

 保存方式二:将数据保存到redis中去(初级方式,比较少用)

当我自己定义这个app.session_interface=Redissessioninterface的时候,session就会保存到redis中去信息就会按照这个类中定义的方法去执行

 

 

然后往下走,到了视图函数,对session有写入的操作

 

 

 

 

 

六、Session

除请求对象之外,还有一个 session 对象。它允许你在不同请求间存储特定用户的信息。它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名要使用会话,你需要设置一个密钥。

  • 设置:session['username'] = 'xxx'

  • 删除:session.pop('username', None)

基本使用

from flask import Flask, session, redirect, url_for, escape, request
 
app = Flask(__name__)
 
@app.route('/')
def index():
    if 'username' in session:
        return 'Logged in as %s' % escape(session['username'])
    return 'You are not logged in'
 
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    return '''
        <form action="" method="post">
            <p><input type=text name=username>
            <p><input type=submit value=Login>
        </form>
    '''
 
@app.route('/logout')
def logout():
    # remove the username from the session if it's there
    session.pop('username', None)
    return redirect(url_for('index'))
 
# set the secret key.  keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
View Code

自定义session

        pip3 install Flask-Session
        
        run.py
            from flask import Flask
            from flask import session
            from pro_flask.utils.session import MySessionInterface
            app = Flask(__name__)

            app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
            app.session_interface = MySessionInterface()

            @app.route('/login.html', methods=['GET', "POST"])
            def login():
                print(session)
                session['user1'] = 'alex'
                session['user2'] = 'alex'
                del session['user2']

                return "内容"

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

        session.py
            #!/usr/bin/env python
            # -*- coding:utf-8 -*-
            import uuid
            import json
            from flask.sessions import SessionInterface
            from flask.sessions import SessionMixin
            from itsdangerous import Signer, BadSignature, want_bytes


            class MySession(dict, SessionMixin):
                def __init__(self, initial=None, sid=None):
                    self.sid = sid
                    self.initial = initial
                    super(MySession, self).__init__(initial or ())


                def __setitem__(self, key, value):
                    super(MySession, self).__setitem__(key, value)

                def __getitem__(self, item):
                    return super(MySession, self).__getitem__(item)

                def __delitem__(self, key):
                    super(MySession, self).__delitem__(key)



            class MySessionInterface(SessionInterface):
                session_class = MySession
                container = {}

                def __init__(self):
                    import redis
                    self.redis = redis.Redis()

                def _generate_sid(self):
                    return str(uuid.uuid4())

                def _get_signer(self, app):
                    if not app.secret_key:
                        return None
                    return Signer(app.secret_key, salt='flask-session',
                                  key_derivation='hmac')

                def open_session(self, app, request):
                    """
                    程序刚启动时执行,需要返回一个session对象
                    """
                    sid = request.cookies.get(app.session_cookie_name)
                    if not sid:
                        sid = self._generate_sid()
                        return self.session_class(sid=sid)

                    signer = self._get_signer(app)
                    try:
                        sid_as_bytes = signer.unsign(sid)
                        sid = sid_as_bytes.decode()
                    except BadSignature:
                        sid = self._generate_sid()
                        return self.session_class(sid=sid)

                    # session保存在redis中
                    # val = self.redis.get(sid)
                    # session保存在内存中
                    val = self.container.get(sid)

                    if val is not None:
                        try:
                            data = json.loads(val)
                            return self.session_class(data, sid=sid)
                        except:
                            return self.session_class(sid=sid)
                    return self.session_class(sid=sid)

                def save_session(self, app, session, response):
                    """
                    程序结束前执行,可以保存session中所有的值
                    如:
                        保存到resit
                        写入到用户cookie
                    """
                    domain = self.get_cookie_domain(app)
                    path = self.get_cookie_path(app)
                    httponly = self.get_cookie_httponly(app)
                    secure = self.get_cookie_secure(app)
                    expires = self.get_expiration_time(app, session)

                    val = json.dumps(dict(session))

                    # session保存在redis中
                    # self.redis.setex(name=session.sid, value=val, time=app.permanent_session_lifetime)
                    # session保存在内存中
                    self.container.setdefault(session.sid, val)

                    session_id = self._get_signer(app).sign(want_bytes(session.sid))

                    response.set_cookie(app.session_cookie_name, session_id,
                                        expires=expires, httponly=httponly,
                                        domain=domain, path=path, secure=secure)
View Code

 在setting中设置超时时间

 

 问题:只能对第一级到内容进行修改不能对第二级的内容进行修改

 当在一个登录后的函数对session 中的第二级的值进行了修改,不会保存

session["user"]={"k1":"v1"}

用户登录之后, 先进入index并对session中的字典中的值进行了修噶,修改之后看到如下

 

打印的结果

 但是当在此之后访问test

问题出现了

 解决方案

 

 方案二       需要改两段   一个是login中的内容,二是修改配置文件中的内容

 

 

源码

 

修改session保存的位置的方式三:  最常用

在settings中修改的内容

#encoding=utf-8
import datetime
from redis import Redis
class Config(object):
    SECRET_KEY='sdafasd'
    DEBUG = False
    TESTING = False
    DATABASE_URI = 'sqlite://:memory:'
    SEND_FILE_MAX_AGE_DEFAULT= datetime.timedelta(hours=12 )
    SESSION_TYPE='redis'

class ProductionConfig(Config):
    DATABASE_URI = 'mysql://user@localhost/foo'
    #上线版本就写上线的redis的ip
    SESSION_REDIS = Redis(host='196.12.21.33', port='6379')


class DevelopmentConfig(Config):
    DEBUG = True
    #测试版本 就写本机的redis地址
    SESSION_REDIS = Redis(host='127.0.0.1', port='6379')


class TestingConfig(Config):
    TESTING = True

在 __init__中修改的内容

#encoding=utf-8
from flask import Flask
from .views import account
from .views import home
from flask_session import Session

def creatapp():
    app=Flask(__name__)
    #选择配置settings中的哪一个类作为使用的配置类(注意写法)
    app.config.from_object("settings.DevelopmentConfig")
    #将蓝图注册到这个app中
    app.register_blueprint(account.account)
    app.register_blueprint(home.home)
    #将session替换成redissession
    Session(app)
    return app

 

 

posted on 2018-05-01 15:33  王大拿  阅读(226)  评论(0编辑  收藏  举报

导航