上一篇讲完了 Cookie,那 Session 又是什麽?
Session 就像是麦X劳的点点卡,给顾客一个卡片,只要顾客使用这张卡片,商店本身就可以查到使用者的资料。
Session 也是一样,交给使用者一笔 Cookie,里面记录着一些资讯,并且(理论上应该只有) Server 可以取得有关的资讯。
看到这边是不是还不知道资讯是如何记录的、又记录在哪对吧!因为又可以细分为两种:
Server Side Session
资讯储存在 Server 那侧(对,我没说在 Server 上,因为资料库可以跟 Server 分开),并且 Server 只交给使用者一个 session_id。只要使用者拿着这个 ID,Server 就可去找到资料来认识使用者(前提是 Session 没过期)。
就类似会员卡一样,卡片本身不纪录任何除了卡号以外的所有资讯,顾客拿着会员卡,刷一下卡号就可以在商店的纪录上找到这个使用者,而卡号本身并没有任何意义。
Client Side Session
资讯加密过後(重点就是这个加密,不加密就属於 Cookie 了),储存在 Client 的 Cookie 上,并且(理论上应该只有) Server 端能够解密看到原始的资讯。
就类似悠游卡一样(虽然这个举例并不好,但 get 到重点就好),卡片本身纪录了一部分资讯(不太可能全部啦,全部的话 Cookie 早就爆掉了),悠游卡上面记录着一部分加密後的资讯,但是只有商店能够解密获得原本的资讯。
大概知道了 Session 的分类了之後,那 Flask 又属於哪一种呢?
Flask 本身所使用的 Session 是属於 Client Side Session。要做到 Server Side Session 可以透过 Flask-Session 这个扩充套件达成。
在开始 Session 前要先设定好 SECRET_KEY,如何设定 SECRET_KEY 呢?
首先要先生成一个 SECRET_KEY,直接在 cmder 执行这行。
python -c "import os;print(os.urandom(16))"
执行完後界可以得到一组随机产生的 SECRET_KEY,然後在 app.py
中设定(或是放在设定档後载入)。
app.py
from flask import Flask, session
app = Flask(__init__)
# 设定好刚刚的 SECRET_KEY,提醒一下,这个最好自己生成喔!
app.config['SECRET_KEY'] = b'>\x89k\xff.t{\xed\xc0\x8c^E\x81A\xe7\xb6'
其他相关设定
# PERMANENT_SESSION_LIFETIME:设置 session 的有效期 = Cookie 的过期时间,单位是秒。默认 Session 是永久,当 session.permanent 为 True 时才会套用。
# SESSION_COOKIE_NAME: 返回给客户端的 Cookie 的名称,默认是 "session"
# SESSION_COOKIE_DOMAIN: 设置 Session 的 Domain
# SESSION_COOKIE_PATH: 设置 Session 的 Path
# SERVER_NAME: 设置 Server name,不常使用
# SESSION_COOKIE_SECURE: 如果为 True,那麽只会使用 HTTPS 发送,默认为 False。
# APPLICATION_ROOT: 根路径。
# SESSION_REFRESH_EACH_REQUEST: 是否应该为每一个请求设置cookie,默认为True,如果为False则必须显性调用set_cookie函数;
# SESSION_COOKIE_HTTPONLY:默认为 True,表示允许 JavaScript 使用 Cookie
这样就可以了。接着改原本的架构:
ithome
├── static
│ └── logo.svg
├── templates
│ ├── res
│ │ ├── home.html
│ │ ├── index.html
│ │ ├── login.html
│ │ ├── page_not_found.html
│ │ └── settings.html
│ └── base.html
├── app.py
├── configs.py
├── Pipfile
└── Pipfile.lock
app.py
@app.route('/')
def index():
return render_template('res/index.html')
@app.route('/home', methods=['GET'])
def home():
if 'username' in session:
user = session['username']
else:
user = None
return render_template('res/home.html', username=user)
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET': # 输入网址会进到这里
response = make_response(render_template('res/login.html'))
# expire_date = datetime.datetime.now() - datetime.timedelta(days=30)
# response.set_cookie('username', '')
elif request.method == 'POST': # 表单送出後会到这里
account = request.values.get('username', None)
# 验证是否有这个使用者以及密码是否正确,生出验证结果 auth_result
auth_result = 'success' # 假设成功
''' 建立回应 '''
if auth_result == 'success': # 如果都正确
response = make_response(redirect(url_for('home')))
''' 设定 Session '''
session['username'] = account
else: # 如果错误
response = make_response(redirect(url_for('login')))
else:
response = make_response(redirect(url_for('index')))
return response
@app.route('/settings', methods=['GET'])
def settings():
if 'username' in session:
user = session['username']
else:
user = None
return render_template('res/settings.html', username=user)
大概就这样就可以了,不用特别将 Session 塞入 response,因为 Flask 会自动带入。
如果想要达成 Server Side Session,可以透过 Flask_session 这个套件达成,使用方式大致相同,只是除了上面设定的部分以外,多了一些关於如何储存的设定而已。
SESSION_TYPE: 设定如何储存。选项有下面这几种
null(default): 使用 Flask 预设的方式。(你都特别装了这个插件,用点其它的不好吗?其它的不香吗?就非得用它吗?)
redis: 就用 Redis 的 Type 存在 Redis 里面,Redis 会储存在记忆体里面。
相关设定:
SESSION_REDIS: Redis 的位置,预设为: 127.0.0.1:6379
memcached: 跟 Redis 差不多,只是变成是用 MemCache 存在记忆体里面。
相关设定:
SESSION_MEMCACHED: MemCache 的位置,预设为: 127.0.0.1:11211
filesystem: 存在文件中。
相关设定:
SESSION_FILE_DIR: 文件位置,预设为目前工作资料夹。
SESSION_FILE_THRESHOLD: Session 最大项目数,预设为 500。
SESSION_FILE_MODE: 文件模式,预设为 0600(大概就是 chmod 0600 的意思)。
mongodb: 就是存在 MongoDB 中。
相关设定:
SESSION_MONGODB: MongoDB 的位置,预设为: 127.0.0.1:27017。
SESSION_MONGODB_DB: 大概就是 MongoDB 的资料库名称的意思,预设为: "flask_session"。
SESSION_MONGODB_COLLECT: 大概就是 MongoDB 的资料表名称的意思,预设为: "sessions"。
sqlalchemy: 存在关联式资料库中。
相关设定:
SESSION_SQLALCHEMY: SQLAlchemy 的实例。资料库 URL 使用 SQLALCHEMY_DATABASE_URI 的设定。
SESSION_SQLALCHEMY_TABLE: 资料表名称,预设为: "sessions"。
SESSION_PERMANENT: Session 期限是否为永久,预设为 True。
SESSION_USE_SIGNER: 加密 Session,预设为 False;设为 True 需设置 SECRET_KEY。
SESSION_KEY_PREFIX: 存在资料库中的 KEY 的前缀,预设为 session"。
那麽就大概这样,Cookie 跟 Session 在网页的技术中是基础但很重要的技术,真的要学好。
大家掰~掰~
<<: [DAY27]GCP-Google Cloud Platform
前言 Hi 我是一名普通的 iOS 开发者,兴趣使然的 UI 设计师。不小心参与了几年 iOS 开发...
Azure Sentinel提供资料表来储存可供Kusto查询语言(KQL)查询存取的清单资料。 A...
哈罗大家好~ 昨天我们初步认识了 Dynamic 365,那 Dynamic 365 与 Micro...
前置作业安装 node vue vue-cli vue-cli(Vue.js Command-Lin...
前言 昨天花了很大的篇幅在学习spinlock ,可惜最重要的一部分 queued spinlock...