Flask和Jinja2的if语句总是评估为False

1 投票
1 回答
27 浏览
提问于 2025-04-12 16:14

我正在我的网站上实现一个管理页面,但即使我输入了正确的凭据,它仍然显示“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)

注意:凭据都是管理员权限(在.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 %}

在app.py中,即使我传递了1,admin.html中的if authenticated判断结果却是false。
这个网址是 http://127.0.0.1:5001/admin?authenticated=1
我用flask run --debug --port 5001命令启动了flask服务器。
我该如何解决这个问题,以便在登录后显示管理页面的内容呢?

1 个回答

0

你在把认证参数传给管理员页面时,发现从登录函数跳转的时候,没有正确传递这个认证参数。

在你的登录函数中,当成功登录后跳转到管理员页面时,需要把认证参数作为网址的一部分传过去。你可以这样做:

from flask import request, redirect, url_for

@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))  # Passing authenticated=1
    else:
        return render_template('login.html', incorrect=True)

这样一来,当登录成功后,就会跳转到管理员页面,并且认证参数会被设置为1。

另外,你似乎在管理员页面的路由中使用了一个默认的认证参数,这其实是不必要的,因为你已经明确地传递了这个参数。你可以修改你的管理员路由:

@app.route('/admin')
def admin():
    authenticated = request.args.get('authenticated', default=0, type=int)
    if authenticated:
        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)
    else:
        return render_template('admin.html', authenticated=authenticated)

这样应该就能正常工作了。

撰写回答