khóa bí mật chưa được đặt trong phiên bình, bằng cách sử dụng tiện ích mở rộng Phiên bình


83

Hiện tại, tôi đang sử dụng thư viện bên thứ ba Flask-Session và tôi không gặp may khi phiên hoạt động.

Khi tôi kết nối với trang web của mình, tôi gặp lỗi sau:

RuntimeError: phiên không khả dụng vì không có khóa bí mật nào được đặt. Đặt secret_key trên ứng dụng thành một thứ gì đó độc đáo và bí mật.

Dưới đây là mã máy chủ của tôi.

from flask import Flask, session
from flask.ext.session import Session

SESSION_TYPE = 'memcache'

app = Flask(__name__)
sess = Session()

nextId = 0

def verifySessionId():
    global nextId

    if not 'userId' in session:
        session['userId'] = nextId
        nextId += 1
        sessionId = session['userId']
        print ("set userid[" + str(session['userId']) + "]")
    else:
        print ("using already set userid[" + str(session['userId']) + "]")
    sessionId = session.get('userId', None)
    return sessionId

@app.route("/")
def hello():
    userId = verifySessionId()
    print("User id[" + str(userId) + "]")
    return str(userId)

if __name__ == "__main__":
    app.secret_key = 'super secret key'

    sess.init_app(app)

    app.debug = True
    app.run()

Như bạn có thể thấy, tôi đã đặt khóa bí mật của ứng dụng. Tôi đang làm gì sai?

Có các tùy chọn phiên khác không?

Thông tin khác: Chạy Python 2.7 trên Linux Mint

Toàn bộ dán:

Traceback (most recent call last):
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/sean/code/misc/session/sessiontest.py", line 27, in hello
    userId = verifySessionId()
  File "/home/sean/code/misc/session/sessiontest.py", line 16, in verifySessionId
    session['userId'] = nextId
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/werkzeug/local.py", line 341, in __setitem__
    self._get_current_object()[key] = value
  File "/home/sean/code/misc/hangman/venv/lib/python2.7/site-packages/flask/sessions.py", line 126, in _fail
    raise RuntimeError('the session is unavailable because no secret '
RuntimeError: the session is unavailable because no secret key was set.  Set the secret_key on the application to something unique and secret.

Là gì traceback đầy đủ của ngoại lệ?
Martijn Pieters

Flask-Sessionbạn đang sử dụng phiên bản nào? Tôi không thể tìm thấy bất kỳ tham chiếu nào về ngoại lệ đó trong nguồn dự án hiện tại .
Martijn Pieters

@MartijnPieters Bất kỳ ý tưởng nào tôi có thể tìm ra điều đó? Tôi chỉ một pip cài đặt cho nó
MintyAnt

Đã tìm thấy thông báo ngoại lệ; nó nằm trong chính Flask, không phải Flask-Session.
Martijn Pieters

@MartijnPieters Tôi đã thêm theo dõi đầy đủ. Nó xuất hiện khi tôi cố gắng để thiết lập phím 'userId', như bạn có thể nhìn thấy
MintyAnt

Câu trả lời:


96

Trong trường hợp của bạn, ngoại lệ được đưa ra bởi NullSessionInterfacetriển khai phiên, là loại phiên mặc định khi bạn sử dụng Flask-Session. Đó là bởi vì bạn chưa bao giờ thực sự cung cấp SESSION_TYPEcấu hình cho Flask ; nó không đủ để đặt nó làm toàn cục trong mô-đun của bạn. Các Flask-Session quickstart mã ví dụ không thiết lập một toàn cầu, nhưng sau đó sử dụng các mô-đun hiện như một đối tượng cấu hình bằng cách gọi app.config.from_object(__name__).

Mặc định này không có nhiều ý nghĩa với Flask 0.10 hoặc mới hơn; NullSessioncó thể có ý nghĩa với Flask 0.8 hoặc 0.9, nhưng trong phiên bản hiện tại, flask.session.NullSessionlớp này được sử dụng như một tín hiệu lỗi. Trong trường hợp của bạn, nó cung cấp cho bạn thông báo lỗi sai ngay bây giờ.

Đặt SESSION_TYPEtùy chọn cấu hình thành một thứ khác. Chọn một trong redis, memcached, filesystemhay mongodb, và chắc chắn để thiết lập nó trong app.config(trực tiếp hoặc thông qua nhiều Config.from_*phương pháp ).

Để kiểm tra nhanh, đặt nó thành filesystemdễ nhất; có đủ cấu hình mặc định ở đó để hoạt động mà không cần phụ thuộc thêm:

if __name__ == "__main__":
    app.secret_key = 'super secret key'
    app.config['SESSION_TYPE'] = 'filesystem'

    sess.init_app(app)

    app.debug = True
    app.run()

Nếu bạn thấy lỗi này và bạn không sử dụng Flask-Session, thì đã xảy ra sự cố với việc đặt bí mật. Nếu bạn đang thiết lập app.config['SECRET_KEY']hoặc app.secret_keytrong một chế độ if __name__ == "__main__":bảo vệ như trên và gặp lỗi này, thì có thể bạn đang chạy ứng dụng Flask của mình thông qua máy chủ WSGI nhập dự án Flask của bạn dưới dạng mô-đun__name__ == "__main__"khối không bao giờ chạy.

Dù sao thì việc quản lý cấu hình cho các ứng dụng Flask trong một tệp riêng luôn tốt hơn .


3
Lưu ý rằng sử dụng app.secret_keylà thực hành không tốt. Tốt hơn là đặt khóa bí mật thông qua app.configđối tượng, điều này cho phép bạn giảm tải cấu hình sang tệp bên ngoài.
Miguel

4
Lưu ý cho người dùng Heroku kết thúc ở đây: Tôi đã không nhận được ví dụ ở đây để làm việc cho đến khi tôi di chuyển app.secret_key = ...ra khỏi nếu khối - mà trong nhận thức muộn màng làm cho tinh thần kể từ Heroku chạy ứng dụng qua gunicorn, có nghĩa là if __name__ == "__main__":khối không bao giờ được nhập vào.
Pascal

'Đặt khóa bí mật bên ngoài if name ==' main ':' câu trả lời tại đây của stackoverflow.com/users/2900124/hayden bên dưới là câu trả lời tốt hơn (hoạt động trên máy chủ được lưu trữ, trong khi câu trả lời này thì không)
ng10

@ ng10: câu trả lời đó áp dụng khi bạn không sử dụng Flask-Session . Vấn đề trong câu hỏi ở đây là thông báo lỗi bạn thấy khi sử dụng Flask-Session không hữu ích và sai. Nếu bạn thấy thông báo lỗi khi không sử dụng Flask-Session, thì câu trả lời khác có thể áp dụng. Tôi đã cập nhật câu trả lời để giải quyết cả hai tùy chọn.
Martijn Pieters

1
@iamai: đó là phần Cấu hình phiên-Flask ; đối với mongodb, tên cơ sở dữ liệu mặc định là flask_sessionvà bộ sưu tập mặc định được gọi sessions.
Martijn Pieters

59

Đặt khóa bí mật bên ngoài if __name__ == '__main__':

app.py:

from flask import Flask, session

app = Flask(__name__)
app.secret_key = "super secret key"

@app.route("/")
...

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

Khi bạn khởi động ứng dụng của mình bằng cách chạy flask run, if __name__ == '__main__':khối sẽ bị bỏ qua. Nếu bạn không muốn bỏ qua nó, hãy chạy với python app.py.


Tôi đang chạy một ứng dụng flask trên máy chủ Ubuntu amazon ec2 apache2, sử dụng oauth2.0 để truy cập thông tin lịch của google. Câu trả lời này là sửa đổi đơn giản đã làm cho nó hoạt động. Cảm ơn bạn!
jas

Đây là câu trả lời cho một câu hỏi khác , một câu hỏi trong đó loại phiên đã được định cấu hình chính xác hoặc bạn hoàn toàn không sử dụng Flask-Session, nhưng không có bí mật nào được đặt bởi vì máy chủ WSGI đã tải mô-đun bằng nhập chứ không phải như kịch bản chính.
Martijn Pieters

14

Thử cái này:

app = Flask(__name__)
app.config['SESSION_TYPE'] = 'memcached'
app.config['SECRET_KEY'] = 'super secret key'
sess = Session()

Và xóa app.secret_keybài tập của bạn ở dưới cùng.


Tôi đã bắn nó, không may mắn, cùng một lỗi. Tôi có thể cập nhật mã bài đăng nếu bạn muốn
MintyAnt.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.