Flask的session

session主要用来记录登录状态,一般基于cookie实现的。之前在Django的session中我也说过这些session,这里面主要说下Flask的session。

Flask的默认session利用了Werkzeug的SecureCookie,它的基本思想是把相关信息做序列化后编码(base64),加上各种防篡改值、时间序列等等,然后放到cookie里,当有请求再次到来时,会根据cookie信息得到session。


看到这,你应该明白,flask的session是通过客户端的cookie实现的,不同于diango的服务器端实现,它在Cookie中会设置一个键值为session的字段。后面跟着一大堆谁也不明白啥意思的字符串。如下:

HTTP/1.0 200 OK
Content-Length: 13
Content-Type: text/html; charset=utf-8
Date: Wed, 01 Mar 2017 04:20:54 GMT
Server: Werkzeug/0.11.2 Python/2.7.10
Set-Cookie: session=eyJ1c2VybmFtZSI6ImNpeml4cyJ9.C5fdpg.fqm3FTv0kYE2TuOyGF1mx2RuYQ4; HttpOnly; Path=/

有了session,我们开发者就可以直接在视图函数中用了,session和request一样,都是RequestCtx中的变量。

那说到这,session是基于客户端存储的,那它怎样来保证安全性呢?

flask通过itsdangerous(一种签名算法,主要使用HMAC加密算法)将session的内容序列化到浏览器的cookie,当浏览器再次请求时将反序列化cookie内容,也就得到我们的session内容。

为了防止cookie内容被篡改,session会自动打上一个叫session的hash串,这个串是经过session内容、SECRET_KEY计算出来的,看得出,这种设计虽然不能保证session里的内容不泄露,但至少防止了不被篡改。
浏览器得到的cookie由三部分组成:内容序列化+时间+防篡改值。
第二部分保存的是时间,itsdangerous库为了减少时间戳的值,之前减掉了118897263,所以我们要加上。flask是用这个时间判断session是否过期使用的。 第三部分是session值和时间戳以及我们SECRET_KEY的防篡改值,通过HMAC算法签名。也就是说即使你修改了前面的值,由于签名值有误,flask不会使用该session。

def get_signing_serializer(self, app):
    if not app.secret_key:
        return None
    signer_kwargs = dict(
        key_derivation=self.key_derivation,
        digest_method=self.digest_method
    )
    return URLSafeTimedSerializer(app.secret_key,
        salt=self.salt,
        serializer=self.serializer,
        signer_kwargs=signer_kwargs)

 

--------EOF---------
微信分享/微信扫码阅读