【问题标题】:Flask: How do you redirect to the same page with the same address, but with different content?Flask:如何重定向到具有相同地址但内容不同的同一页面?
【发布时间】:2022-01-21 22:05:56
【问题描述】:

我创建了一个使用数据库进行简单登录的网站。我想要它,以便当您访问主页时,它会提示您注册/登录;当你登录时,它会重定向到同一个主页,但主页不能显示提示(暗示你已经登录),而是显示仅供登录用户使用的内容。所以它的路由必须仍然是“/”。我试过这个:

<meta http-equiv="refresh" content="0; url={{ url_for('index', authenticated=1) }}">

在我的 Python 文件中:

build = Flask(__name__)
@build.route('/')
def index(authenticated=0):
    if authenticated == 0:
        return render_template("index.html")
    elif authenticated == 1:
        return render_template("main.html")

我为什么要这样?嗯.. 我不希望新用户访问该专有链接。因此,除非有一种解决方法可以让独占链接检测到新用户是否未登录,否则我不知道有任何其他方法可以完成此操作

【问题讨论】:

  • 您通常将身份验证信息存储在 cookie 中。也许看看Flask-Loginflask-login.readthedocs.io/en/latest
  • 是的,但我已经使用了 SQLAlchemy。好吧,我会用它作为最后的手段,谢谢
  • Flask-Login 与 SQLAlchemy 一起工作

标签: python html flask


【解决方案1】:

您也可以通过创建两条不同的路线来做到这一点。

例如,这里的admin 路由是为登录用户提供的,home 是为普通用户提供的。如果用户通过身份验证,它会重定向到admin func。

@app.route("/login", methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated:
            return redirect(url_for('admin'))
        else:
            return redirect(url_for('home'))

@app.route("/admin")
def admin():
    return render_template('admin_home.html')

@app.route("/home")
def home():

    return render_template('home.html')

【讨论】:

  • 好吧,这绝对有效。但是我怎么能喜欢将它们混合成一条路线并让它们工作
  • 这里也可以直接重定向 HTML 页面,但是建议使用上述方法,如果需要,可以添加更多逻辑和条件。
  • 嗯。但是新用户/未注册用户可以通过编辑/admin的链接进入登录用户的专属页面吗?我不认为登录功能可以阻止它
  • 是的,你就在这里,所以你也可以在这里设置条件,比如用户是否通过身份验证然后重定向到主页,否则重定向到登录页面。
【解决方案2】:

您必须使用这样的重定向:

from flask import Flask, redirect, render_template

app = Flask(__name__)

@app.route("/")
def index():
    if authenticated == 0:   
        return redirect('/login')
    return render_template("index.html")

@app.route("/login")
def login():
    if authenticated == 1:   
        return redirect('/')
    return render_template("index.html")

【讨论】:

  • 感谢您的评论,但这并没有真正奏效。它重定向到主页,路由为/?authenticated=1,而不是原来的/
  • 其不好的做法是通过查询字符串传输 authenticated=1。您可以将身份验证标志保存到您的应用程序(数据库或全局变量)中并检查它。但更好的是使用JWT进行身份验证pythonhosted.org/Flask-JWT
【解决方案3】:

我解决了。对于正在阅读本文的其他人,这是我的解决方案: 首先你需要导入flask_login并且你必须安装它,你可以通过pip install flask_login来做。 然后,在你的 python 文件中,你需要导入这些:

from flask_login import UserMixin, login_user, LoginManager, login_required, logout_user, current_user

之后,创建您的app 并配置您的flask_login

app= Flask(__name__)
db = SQLAlchemy(app) # this is my database file, if you've already created it than you can leave it out
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login' # REPLACE login WITH YOUR LOGIN ROUTE, BUT DO NOT INCLUDE A SLASH (/) AND MUST BE IN QUOTES
login_manager.login_message = "You must be logged-in in order to view this page." # OPTIONAL: A CUSTOM FLASH MESSAGE THAT WILL BE SHOWN WHEN A SIGNED-OUT USER TRIES TO ACCESS PAGES THAT REQUIRE A LOGIN. YOU CAN DELETE IT IF YOU WANT THE DEFAULT MESSAGE

@login_manager.user_loader
def user(id):
    return Clients.query.get(int(id)) # REPLACE Clients WITH YOUR USER CLASS THAT IS USED TO AUTHENTICATE (NORMALLY IT INHERITS A DATABASE MODEL AND USERMIXIN)

最后,滚动到要限制的函数并应用@login_required 装饰器(从flask_login 导入),它必须在@app.route() 之后

@app.route('/exclusive_page_for_logged_in_users')
@login_required
def exclusive_page():
    return render_template('exclusive_page.html')

回答我原来的问题:

@build.route('/')
def index():
    if current_user.is_authenticated:
        return render_template("index.html")
    else:
        return render_template("authenticate.html")

您可以看到条件current_user.is_authenticated。不要替换任何东西,因为这就是它的本意。该条件检查用户是否登录,如果您未登录,它将加载authenticate.html 而不是index.html,同时保持相同的路线;因此您看不到 @login_required 装饰器。

现在,您如何登录?您可以使用login_user(YOUR_USER_INFO_FROM_DB) 这很简单,但你需要一个数据库来做到这一点。你可以在你的数据库中搜索信息来验证它们,这里我就不一一列举了。

pw_check_validation = Clients.query.filter_by(auth_name=auth_name).first()

login_user(pw_check_validation)

flash(f"Login successful.")
return redirect(url_for("index"))

要注销,一个简单的logout_user() 就可以了。

# My code for log out    
@build.route("/end_session/?db_ID=<int:id>")
@login_required
def logout(id):
    logout_user()
    flash("You have been logged out.")
    return redirect(url_for('authenticate'))

希望对遇到同样问题的人有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    • 2016-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多