首页 > 解决方案 > 会话不是持久的,即使在 Flask 中设置了密钥

问题描述

我有一个挑剔的问题。我已经对一个以前在开发服务器上愉快运行的烧瓶应用程序进行了 docker 化。数据库连接正常工作,页面呈现等。但它会在每个页面加载时删除会话 - 这意味着,由于我已经拥有“你是否登录”保护,我在每次导航时都会被分流回登录页面. 我已经在配置文件中设置了密钥。在 .py 文件中的纯文本中。作为一个变量,从文本文件中提取 - 每次,它都会显示在 app.config 中。每次,会话都不会保持活动状态。有人有新的见解吗?我正在失去理智。

让我知道您是否需要查看其他部分以进行诊断。. 我没有收到错误,但我确实在底部包含了控制台输出。

码头工人组成:

version: "3.7"
services:
  db:
    image: mysql:8.0.19
    command: '--default-authentication-plugin=mysql_native_password'
    restart: always
    secrets:
      - db-password
    volumes:
      - ./db:/docker-entrypoint-initdb.d/:ro
    networks:
      - backnet
    environment:
      - MYSQL_DATABASE=example
      - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db-password
    ports:
      - 3306:3306
  backend:
    build: backend
    restart: always
    secrets:
      - db-password
    ports:
      - 5000:5000
    networks:
      - backnet
      - frontnet
  proxy:
    build: proxy
    restart: always
    ports:
      - 80:80
    networks:
      - frontnet
volumes:
  db-data:
secrets:
  db-password:
    file: db/password.txt
networks:
  backnet:
  frontnet:

Dockerfile:

FROM python:3.8.5

WORKDIR /code

ADD requirements.txt /code/

RUN pip install -r requirements.txt

COPY . /code/

ENV FLASK_APP main.py
ENV FLASK_ENV development

CMD flask run --host=0.0.0.0

main.py 的顶部(减去导入,因为很长):

    app = Flask(__name__)
    
    ## Configuration: DOCKER, +CONFIG FILE
    if app.config["ENV"] == "production":
        app.config.from_object("config.ProductionConfig")
    else:
        app.config.from_object("config.DevelopmentConfig")

    # Set the secret key, because no other method seems to stick... and neither does this. yay. 
    sk = open("secret_key_file", 'r')
    app.secret_key = sk.read()
    sk.close()
    print(app.config, file=sys.stderr)

@app.route('/kartayl/', methods=['GET', 'POST'])
def login():
    print("LOGIN ROUTE CALLED ----------------------------", file=sys.stderr)
    if hasattr(session, 'id'):
        print('SESSION ID: ', session['id'], file=sys.stderr)
    else:
        print('----------------NO SESSION ID-----------------', file = sys.stderr)
    # Output message if something goes wrong...
    msg = ''
    # Check if "username" and "password" POST requests exist (user submitted form)
    if request.method == 'POST' and 'username' in request.form and 'password' in request.form:
        # Create variables for easy access
        username = request.form['username']
        session['username'] = username
        print(username, file=sys.stderr)
        password = request.form['password']
        # Check if account exists using MySQL
        cursor = kartayl.connection.cursor(MySQLdb.cursors.DictCursor)
        cursor.execute('SELECT * FROM USER_ACCOUNTS WHERE username = %s AND password = %s AND login_allowed=TRUE', (thwart(username), thwart(password)))
        # Fetch one record and return result
        account = cursor.fetchone()
        # If account exists in USER_ACCOUNTS table in database
        if account:
            # Create session data, we can access this data in other routes
            print("ACCOUNT QUERY RETURNED A VALUE", file=sys.stderr)
            print(account, file=sys.stderr)
            session['loggedin'] = True
            session['id'] = account['user_id']
            session['username'] = account['username']
            # Redirect to home page
            return render_template('home.html', username=session['username'])
        else:
            # Account doesnt exist or username/password incorrect
            msg = 'Incorrect username/password!'
    # Show the login form with message (if any)
    return render_template('index.html', msg=msg)

配置文件

class Config(object):
    DEBUG = False 
    TESTING = False 
    PROPAGATE_EXCEPTIONS = None 
    PRESERVE_CONTEXT_ON_EXCEPTION = None
    SESSION_REFRESH_EACH_REQUEST = False 
    USE_X_SENDFILE = False 
    SERVER_NAME = None 
    APPLICATION_ROOT = '/'
    SECRET_KEY = 'ObiWanisTheBombdotComSoSayethTheMandaloreReallyDatingMyselfWithThisOne'  
    SESSION_COOKIE_NAME = 'session' 
    SESSION_COOKIE_SAMESITE="None"
    SESSION_COOKIE_SECURE = True
    SESSION_COOKIE_HTTPONLY = True
    SESSION_TYPE = 'filesystem'
    JSON_AS_ASCII = True 
    JSON_SORT_KEYS = True 
    JSONIFY_PRETTYPRINT_REGULAR = False 
    JSONIFY_MIMETYPE = 'application/json' 
    TEMPLATES_AUTO_RELOAD = None 
    MAX_COOKIE_SIZE = 4093 
    MYSQL_CURSORCLASS = 'DictCursor'  
    MYSQL_UNIX_SOCKET = None 
    MYSQL_CONNECT_TIMEOUT = 10 
    MYSQL_READ_DEFAULT_FILE = None 
    MYSQL_USE_UNICODE = True 
    MYSQL_CHARSET = 'utf8' 
    MYSQL_SQL_MODE = None

class ProductionConfig(Config):
    pass

class DevelopmentConfig(Config):
    ENV = 'development'
    DEBUG = True
    MYSQL_HOST = 'db' # name of the mysql service as set in the docker-compose file
    MYSQL_PASSWORD = 'nooneknows' 
    MYSQL_USER = 'megs' 
    MYSQL_DB = 'databasename' 

打印 app.config 得到这个,向我表明设置了哔哔声:

    <Config {'ENV': 'development', 'DEBUG': True, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None,
 'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'SECRET_KEY': 'ObiWanisTheBombdotComSoSayethTheMandaloreReallyDatingMyselfWithThisOne', 
'PERMANENT_SESSION_LIFETIME': datetime.timedelta(days=31), 'USE_X_SENDFILE': False, 'SERVER_NAME': None,
 'APPLICATION_ROOT': '/', 'SESSION_COOKIE_NAME': 'session', 'SESSION_COOKIE_DOMAIN': None, 
'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_HTTPONLY': True, 'SESSION_COOKIE_SECURE': True, 
'SESSION_COOKIE_SAMESITE': 'None', 'SESSION_REFRESH_EACH_REQUEST': False, 'MAX_CONTENT_LENGTH': None, 
'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(seconds=43200), 'TRAP_BAD_REQUEST_ERRORS': None, 
'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 
'JSON_AS_ASCII': True, 'JSON_SORT_KEYS': True, 'JSONIFY_PRETTYPRINT_REGULAR': False, 'JSONIFY_MIMETYPE':
 'application/json', 'TEMPLATES_AUTO_RELOAD': None, 'MAX_COOKIE_SIZE': 4093, 'MYSQL_CHARSET': 'utf8',
 'MYSQL_CONNECT_TIMEOUT': 10, 'MYSQL_CURSORCLASS': 'DictCursor', 'MYSQL_DB': 'databasename', 'MYSQL_HOST': 
'db', 'MYSQL_PASSWORD': 'nooneknows', 'MYSQL_READ_DEFAULT_FILE': None, 'MYSQL_SQL_MODE': None, 
'MYSQL_UNIX_SOCKET': None, 'MYSQL_USER': 'megs', 'MYSQL_USE_UNICODE': True, 'SESSION_TYPE': 
'filesystem'}>

控制台,带有打印语句为您提供时间:

megs@BlackTower:~/nginx-flask-mysql$ docker-compose up
Starting nginx-flask-mysql_db_1        ... done
Recreating nginx-flask-mysql_backend_1 ... done
Starting nginx-flask-mysql_proxy_1     ... done
Attaching to nginx-flask-mysql_db_1, nginx-flask-mysql_proxy_1, nginx-flask-mysql_backend_1
backend_1  |  * Serving Flask app "main.py" (lazy loading)
backend_1  |  * Environment: development
backend_1  |  * Debug mode: on
backend_1  |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
backend_1  |  * Restarting with stat
db_1       | 2021-03-28 00:47:19+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.19-1debian10 started.
db_1       | 2021-03-28 00:47:19+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
db_1       | 2021-03-28 00:47:19+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.19-1debian10 started.
db_1       | 2021-03-28T00:47:19.708614Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.
db_1       | 2021-03-28T00:47:19.708713Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.19) starting as process 1
backend_1  |  * Debugger is active!
backend_1  |  * Debugger PIN: 137-018-880
db_1       | 2021-03-28T00:47:23.015306Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
db_1       | 2021-03-28T00:47:23.063799Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
db_1       | 2021-03-28T00:47:23.087863Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.19'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.
db_1       | 2021-03-28T00:47:23.222617Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock' bind-address: '::' port: 33060
backend_1  | <Config {'ENV': 'development', 'DEBUG': True, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None, 'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'SECRET_KEY': 'ObiWanisTheBombdotComSoSayethTheMandalore', 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(days=31), 'USE_X_SENDFILE': False, 'SERVER_NAME': None, 'APPLICATION_ROOT': '/', 'SESSION_COOKIE_NAME': 'session', 'SESSION_COOKIE_DOMAIN': None, 'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_HTTPONLY': True, 'SESSION_COOKIE_SECURE': True, 'SESSION_COOKIE_SAMESITE': 'None', 'SESSION_REFRESH_EACH_REQUEST': False, 'MAX_CONTENT_LENGTH': None, 'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(seconds=43200), 'TRAP_BAD_REQUEST_ERRORS': None, 'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 'JSON_AS_ASCII': True, 'JSON_SORT_KEYS': True, 'JSONIFY_PRETTYPRINT_REGULAR': False, 'JSONIFY_MIMETYPE': 'application/json', 'TEMPLATES_AUTO_RELOAD': None, 'MAX_COOKIE_SIZE': 4093, 'MYSQL_CHARSET': 'utf8', 'MYSQL_CONNECT_TIMEOUT': 10, 'MYSQL_CURSORCLASS': 'DictCursor', 'MYSQL_DB': 'dbname', 'MYSQL_HOST': 'db', 'MYSQL_PASSWORD': 'nooneknows', 'MYSQL_READ_DEFAULT_FILE': None, 'MYSQL_SQL_MODE': None, 'MYSQL_UNIX_SOCKET': None, 'MYSQL_USER': 'megs', 'MYSQL_USE_UNICODE': True, 'SESSION_TYPE': 'filesystem'}>
backend_1  | LOGIN ROUTE CALLED ---------------INITIAL LOAD OF PAGE-------------
backend_1  | ----------------NO SESSION ID-----------------
backend_1  | 172.20.0.2 - - [28/Mar/2021 00:47:39] "GET /kartayl/ HTTP/1.0" 200 -
proxy_1    | 192.168.1.231 - - [28/Mar/2021:00:47:39 +0000] "GET /kartayl/ HTTP/1.1" 200 1298 "http://192.168.1.19/kartayl/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" "-"
backend_1  | 172.20.0.2 - - [28/Mar/2021 00:47:39] "GET /static/css/bootstrap.css.map HTTP/1.0" 200 -
proxy_1    | 2021/03/28 00:47:39 [warn] 7#7: *1 an upstream response is buffered to a temporary file /var/cache/nginx/proxy_temp/1/00/0000000001 while reading upstream, client: 192.168.1.231, server: localhost, request: "GET /static/css/bootstrap.css.map HTTP/1.1", upstream: "http://172.20.0.3:5000/static/css/bootstrap.css.map", host: "192.168.1.19"
proxy_1    | 192.168.1.231 - - [28/Mar/2021:00:47:39 +0000] "GET /static/css/bootstrap.css.map HTTP/1.1" 200 501817 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" "-"
backend_1  | LOGIN ROUTE CALLED ----------------------------
backend_1  | ----------------NO SESSION ID-----------------
backend_1  | test  <-------------THIS IS INPUT FROM THE LOGIN FORM
backend_1  | ACCOUNT QUERY RETURNED A VALUE  --- DATABASE CONNECTION IS GOOD -- LOGIN SUCCESSFUL --
backend_1  | {'user_id': 1, 'username': 'test', 'password': 'test', 'email': 'test@t.com', 'created_at': datetime.datetime(2021, 3, 28, 0, 16, 48), 'marked_for_delete': None, 'color_theme': 'basic', 'login_allowed': 1, 'active_questions': 1}
backend_1  | 172.20.0.2 - - [28/Mar/2021 00:47:44] "POST /kartayl/ HTTP/1.0" 200 -
proxy_1    | 192.168.1.231 - - [28/Mar/2021:00:47:44 +0000] "POST /kartayl/ HTTP/1.1" 200 1896 "http://192.168.1.19/kartayl/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" "-"
backend_1  | 172.20.0.2 - - [28/Mar/2021 00:47:45] "GET /static/js/bootstrap.js.map HTTP/1.0" 200 -
backend_1  | 172.20.0.2 - - [28/Mar/2021 00:47:45] "GET /static/css/bootstrap.css.map HTTP/1.0" 200 -
proxy_1    | 2021/03/28 00:47:45 [warn] 7#7: *6 an upstream response is buffered to a temporary file /var/cache/nginx/proxy_temp/2/00/0000000002 while reading upstream, client: 192.168.1.231, server: localhost, request: "GET /static/css/bootstrap.css.map HTTP/1.1", upstream: "http://172.20.0.3:5000/static/css/bootstrap.css.map", host: "192.168.1.19"
proxy_1    | 192.168.1.231 - - [28/Mar/2021:00:47:45 +0000] "GET /static/js/bootstrap.js.map HTTP/1.1" 200 275227 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" "-"
proxy_1    | 192.168.1.231 - - [28/Mar/2021:00:47:45 +0000] "GET /static/css/bootstrap.css.map HTTP/1.1" 200 501817 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" "-"
backend_1  | 172.20.0.2 - - [28/Mar/2021 00:47:46] "GET /kartayl/dashboard HTTP/1.0" 302 -
proxy_1    | 192.168.1.231 - - [28/Mar/2021:00:47:46 +0000] "GET /kartayl/dashboard HTTP/1.1" 302 225 "http://192.168.1.19/kartayl/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" "-"
backend_1  | LOGIN ROUTE CALLED --------------ACTUALLY CLICKED ON "DASHBOARD" AND WAS REROUTED DUE TO "NOT BEING LOGGED IN" IN THE SESSION--------------
backend_1  | ----------------NO SESSION ID-----------------

标签: pythondockernginxflasksession

解决方案


推荐阅读