簡體   English   中英

處理登錄 Flask web 申請

[英]Handling login Flask web application

我目前正在構建我自己的第一個項目,一個帶有 Flask 的 web 應用程序,它與 Spotify API 交互。經過本地和 Heroku 暫存環境的廣泛測試后,該項目已經准備就緒。 但是,我目前遇到了一個小的登錄“錯誤”,我似乎無法解決這個問題。

單擊“登錄”按鈕時,應用程序會向 Spotify API 發送請求,后者會在用戶確認讀取其數據后發回授權碼。 此確認將導致用戶被重定向到 web 應用程序的“/profile 路由”。 目前為止在不同環境下的登錄流程:

  • 本地:進程一直運行順利(閱讀:單擊“登錄”按鈕一次,將用戶重定向到 /profile 路由)
  • Staging (Heroku) :單擊登錄按鈕會生成對 Spotify API 的正確請求。但是,當我第一次單擊它時,我被重定向到登錄頁面(由於我的 login_required Flask 裝飾器)。 第二次單擊它時,它還會生成正確的請求並正確地將用戶發送到“/profile 路由”。

我可以在服務器日志中看到第一次單擊登錄按鈕會生成正確的請求。 但似乎“/profile 路由”的 login_required 裝飾器的驗證“太快了”? 或者這與緩存有關嗎? 因為我還能夠(有時)通過刪除緩存和硬刷新頁面來重現錯誤。

我最近向 session 添加了一個 SECRET_KEY,並將 SESSION_PERMANENT 從 False 更改為 True,但我認為這不是導致問題的原因? 我認為一些代碼可能會導致這個小錯誤:

# Ensure responses aren't cached
@app.after_request
def after_request(response):
    response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
    response.headers["Expires"] = 0
    response.headers["Pragma"] = "no-cache"
    return response


# Configure session to use filesystem
app.config['SECRET_KEY'] = os.urandom(64)
app.config["SESSION_FILE_DIR"] = mkdtemp()
app.config["SESSION_PERMANENT"] = True
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
def login_required(f):
        """
        Decorate routes to require login:
        http://flask.pocoo.org/docs/1.0/patterns/viewdecorators/
        """
        @wraps(f)
        def decorated_function(*args, **kwargs):
            if session.get("authorization_header") is None:
                return redirect(url_for('login'))
            return f(*args, **kwargs)
        return decorated_function
@app.route("/")
    def index():
        """ Shows landing page """
        if session.get("authorization_header") is not None:
            return redirect(url_for('profile'))
    
        return render_template("index.html")
    
    
    @app.route("/login")
    def login():
        """ Shows login page """
        if session.get("authorization_header") is not None:
            return redirect(url_for('profile'))
    
        return render_template("login.html")
    
    
    @app.route("/logout")
    @helpers.login_required
    def logout():
        """ Logs user out """
        # Forget any user_id
        session.clear()
    
        # Redirect user to login form
        return redirect(url_for("index"))
    
    
    @app.route("/profile")
    @helpers.login_required
    def profile():
       """ Shows overview of user's Spotfy profile """

不確定這是否是您的問題,但可能會導致一些奇怪的行為......

app.config['SECRET_KEY'] = os.urandom(64)這將導致在每個 heroku dyno 上設置不同的密鑰(如果運行多個 worker;同步 worker 的默認值為 2)因為隨機字符串是動態生成的在工人啟動時。

作為旁注, os.urandom不用於生成密鑰。 而是使用secrets模塊,並將生成的字符串設置為 heroku CLI 中的配置變量,並將其加載到您的應用程序中:

import os
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM