You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask中Jinja2的authenticated判断始终为False问题修复求助

问题描述

实现网站管理员页面时,输入正确凭证后跳转至http://127.0.0.1:5001/admin?authenticated=1,但页面仍显示“No Access”。相关代码如下:

app.py

@app.route('/login')
def login():
    return render_template('login.html', incorrect=False)

@app.route('/login', methods=['POST'])
def login_post():
    creds = dict(request.form)
    if creds['username'] == USERNAME and creds['password'] == PASSWORD:
        return redirect(url_for('admin', authenticated=1))
    else:
        return render_template('login.html', incorrect=True)

@app.route('/admin')
def admin(authenticated=0):
    conn = sqlite3.connect('articles.db')
    cur = conn.cursor()
    cur.execute("SELECT * FROM PENDING")
    articles = cur.fetchall()
    #print(articles)
    conn.close()
    return render_template('admin.html', authenticated=authenticated, articles=articles)

注:凭证均为admin(设置在.env文件中)

login.html

{% extends "base.html" %}

{% block title %}Login{% endblock %}
{% block content %}
<div class="write container py-3 mx-auto bg-muted text-white" style="width: 60vw;">
    <h1 action="{{ url_for('write_post') }}" data-aos="fade-up">Admin Login</h1>
    {% if incorrect %}
        <div class="alert alert-danger alert-dismissible">
            <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
            <strong>Incorrect Credentials</strong> Please try again.
        </div>
    {% endif %}
    <form method="POST" enctype=multipart/form-data>
        <label data-aos="fade-up" data-aos-delay="50" for="username">Username:</label><br>
            <input data-aos="fade-up" data-aos-delay="100" required maxlength="255" id="username" name="username"><br><br>
        <label data-aos="fade-up" data-aos-delay="150" for="password">Password:</label><br>
            <input data-aos="fade-up" data-aos-delay="200" required maxlength="255" id="password" name="password"><br><br>
        <input data-aos="fade-up" data-aos-delay="450" class="btn btn-success" type="submit">
    </form>
</div>
{% endblock %}

admin.html

{% extends "base.html" %}

{% block title %}Admin{% endblock %}

{% block content %}
{% if authenticated %}
<div data-aos="fade-down" class=".container p-5 bg-muted text-white">
    <h1>Articles pending review: </h1>
</div>
{% else %}
<div data-aos="fade-down" class=".container p-5 bg-muted text-white">
    <h1>No Access</h1>
    <p>You are not logged in!</p>
</div>
{% endif %}
{% endblock %}

修复方案

问题根源

Flask路由函数的参数不会自动绑定URL查询参数(即?authenticated=1这类参数),当前admin函数的authenticated参数一直使用默认值0,所以模板中{% if authenticated %}始终为假。

另外,用URL参数传递认证状态存在安全隐患——任何人都可以直接修改URL参数获取权限,正确的做法是使用Flask的session存储登录状态。

具体修复步骤

  1. 导入并配置session
    在app.py中导入session和os,设置加密用的SECRET_KEY(建议从.env文件读取,避免硬编码):

    from flask import session
    import os
    
    # 配置SECRET_KEY,用于session加密
    app.secret_key = os.getenv('SECRET_KEY', 'temporary-dev-key')
    
  2. 修改登录逻辑,用session存储认证状态
    更新login_post函数,验证成功后将认证状态存入session,而非通过URL参数传递:

    @app.route('/login', methods=['POST'])
    def login_post():
        creds = dict(request.form)
        if creds['username'] == USERNAME and creds['password'] == PASSWORD:
            session['authenticated'] = True  # 存入session
            return redirect(url_for('admin'))
        else:
            return render_template('login.html', incorrect=True)
    
  3. 修改admin路由,从session获取认证状态
    更新admin函数,从session读取认证状态,未认证时直接返回无权限页面:

    @app.route('/admin')
    def admin():
        # 从session获取认证状态,默认未认证
        authenticated = session.get('authenticated', False)
        
        # 未认证时直接返回无权限页面
        if not authenticated:
            return render_template('admin.html', authenticated=False)
        
        conn = sqlite3.connect('articles.db')
        cur = conn.cursor()
        cur.execute("SELECT * FROM PENDING")
        articles = cur.fetchall()
        conn.close()
        return render_template('admin.html', authenticated=authenticated, articles=articles)
    
  4. 可选:添加退出登录功能
    增加logout路由,清除session中的认证状态:

    @app.route('/admin/logout')
    def logout():
        session.pop('authenticated', None)  # 移除认证状态
        return redirect(url_for('login'))
    

内容的提问来源于stack exchange,提问作者wenbang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 21:48:12