6

以下是 werkzeug 对会话序列化的建议:

默认实现使用 Pickle,因为这是创建此模块时标准库中唯一可用的模块。如果您有 simplejson 可用,强烈建议创建一个子类并替换序列化方法:

当我按照下面的 Flask 实现执行此操作时:

https://gist.github.com/runfalk/2501926

或者

from werkzeug.contrib.securecookie import SecureCookie
Secure_Cookie.serialization_method = json

UnicodeDecodeError:“utf8”编解码器无法解码位置 0 的字节 0x97:无效的起始字节

当我尝试登录时会发生这种情况。

我已经深入研究了 json 编码器源并尝试设置ensure_ascii=False,这让我克服了上面的错误,但后来我根本无法登录应用程序。它只会闪烁屏幕而没有错误,我仍然停留在登录提示符下。用泡菜一切正常。

一个重要的侧面说明这个问题是集成独有的,Flask-login 并且不会发生在普通flask会话序列化中

ASKSBADQUESTIONS 的代码确实有效,但这会引发解码错误

import json

from flask import Flask, session
from flask.sessions import SecureCookieSession, SecureCookieSessionInterface
from flask.ext.login import LoginManager

class JSONSecureCookieSession(SecureCookieSession):
    serialization_method = json

class JSONSecureCookieSessionInterface(SecureCookieSessionInterface):
    session_class = JSONSecureCookieSession

app = Flask(__name__)
app.secret_key = "I-like-cookies-and-some-secure-cookies"
app.session_interface = JSONSecureCookieSessionInterface()

#Initialize Login Manager
login_manager = LoginManager()
login_manager.setup_app(app)

@app.route("/")
def hello():
    k = "lalala"

    v = session.get(k)

    if v is None:
        print "set"
        v = session[k] = "FLAAASK abuses decorators in a bad way :)"
    else:
        print "get"

    return "Hello {0}".format(v)


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

这是堆栈跟踪

Traceback (most recent call last):
  File "/usr/local/pythonbrew/venvs/Python-2.7.3/flask-session-bug/lib/python2.7/site-packages/flask/app.py", line 1701, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/pythonbrew/venvs/Python-2.7.3/flask-session-bug/lib/python2.7/site-packages/flask/app.py", line 1689, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/usr/local/pythonbrew/venvs/Python-2.7.3/flask-session-bug/lib/python2.7/site-packages/flask/app.py", line 1687, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/pythonbrew/venvs/Python-2.7.3/flask-session-bug/lib/python2.7/site-packages/flask/app.py", line 1362, in full_dispatch_request
    response = self.process_response(response)
  File "/usr/local/pythonbrew/venvs/Python-2.7.3/flask-session-bug/lib/python2.7/site-packages/flask/app.py", line 1566, in process_response
    self.save_session(ctx.session, response)
  File "/usr/local/pythonbrew/venvs/Python-2.7.3/flask-session-bug/lib/python2.7/site-packages/flask/app.py", line 804, in save_session
    return self.session_interface.save_session(self, session, response)
  File "/usr/local/pythonbrew/venvs/Python-2.7.3/flask-session-bug/lib/python2.7/site-packages/flask/sessions.py", line 205, in save_session
    secure=secure, domain=domain)
  File "/usr/local/pythonbrew/venvs/Python-2.7.3/flask-session-bug/lib/python2.7/site-packages/werkzeug/contrib/securecookie.py", line 329, in save_cookie
    data = self.serialize(session_expires or expires)
  File "/usr/local/pythonbrew/venvs/Python-2.7.3/flask-session-bug/lib/python2.7/site-packages/werkzeug/contrib/securecookie.py", line 235, in serialize
    self.quote(value)
  File "/usr/local/pythonbrew/venvs/Python-2.7.3/flask-session-bug/lib/python2.7/site-packages/werkzeug/contrib/securecookie.py", line 192, in quote
    value = cls.serialization_method.dumps(value)
  File "/usr/local/pythonbrew/pythons/Python-2.7.3/lib/python2.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/local/pythonbrew/pythons/Python-2.7.3/lib/python2.7/json/encoder.py", line 195, in encode
    return encode_basestring_ascii(o)
UnicodeDecodeError: 'utf8' codec can't decode byte 0x97 in position 0: invalid start byte
set
4

2 回答 2

3

有一个方法flask_login.py被调用_create_identifier。此调用的结果是 md5digest()结果。根据文档,这可以包含非 ascii 字符和/或空字节。当交给serialization_method它时,它无法解码 unicode 字节。

这个错误肯定存在于 Flask 0.9 和 Flask-login 0.1.3 的组合中,可以通过猴子修补这个要点(https://gist.github.com/anonymous/3731115)到 flask_login.py 文件中来修复,或者你可以拉出最新的发展。

如果您需要更多信息 https://github.com/maxcountryman/flask-login/pull/31 ,可以在他们的 github repo 上参考这个错误

于 2013-03-25T15:08:46.830 回答
1

我快速编写了最小的 Flask 应用程序来重现您的错误(保存到app.py; 调用python app.py):

import json

from flask import Flask, session
from flask.sessions import SecureCookieSession, SecureCookieSessionInterface


class JSONSecureCookieSession(SecureCookieSession):
    serialization_method = json


class JSONSecureCookieSessionInterface(SecureCookieSessionInterface):
    session_class = JSONSecureCookieSession


app = Flask(__name__)
app.secret_key = "I-like-cookies-and-some-secure-cookies"
app.session_interface = JSONSecureCookieSessionInterface()


@app.route("/")
def hello():
    k = "lalala"

    v = session.get(k)

    if v is None:
        print "set"
        v = session[k] = "FLAAASK abuses decorators in a bad way :)"
    else:
        print "get"

    return "Hello {0}".format(v)


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

但一切都很顺利。我什session_interface至几次从基于 Pickle 的更改为基于 JSON 的,并没有出现异常。也许您应该发布完整的异常回溯并(也许)在我的示例中添加一些代码以重现错误。

于 2013-03-23T16:02:25.623 回答