Flask/Werkzeug,登录后如何返回上一页

发布于 2024-09-18 06:06:12 字数 1152 浏览 2 评论 0原文

我正在使用基于 Werkzeug 的 Flask 微框架,它使用 Python。

在每个受限页面之前有一个装饰器来确保用户已登录,当前如果用户未登录,则将其返回到登录页面,如下所示:

# Decorator
def logged_in(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        try:
            if not session['logged_in']:
                flash('Please log in first...', 'error')
                return redirect(url_for('login'))
            else:
                return f(*args, **kwargs)
        except KeyError:
            flash('Please log in first...', 'error')
            return redirect(url_for('login'))
    return decorated_function


# Login function
@app.route('/', methods=['GET', 'POST'])
def login():
    """Login page."""
    if request.method=='POST':
    ### Checks database, etc. ###
    return render_template('login.jinja2')


# Example 'restricted' page
@app.route('/download_file')
@logged_in
def download_file():
    """Function used to send files for download to user."""
    fileid = request.args.get('id', 0)
    ### ... ###

登录后,需要将用户返回到将他们带到的页面登录页面。 它还需要保留诸如传递的变量之类的东西(即基本上整个链接 www.example.com/download_file?id=3 )

有谁知道如何做到这一点?

谢谢您的帮助:-)

I am using the Flask micro-framework which is based on Werkzeug, which uses Python.

Before each restricted page there is a decorator to ensure the user is logged in, currently returning them to the login page if they are not logged in, like so:

# Decorator
def logged_in(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        try:
            if not session['logged_in']:
                flash('Please log in first...', 'error')
                return redirect(url_for('login'))
            else:
                return f(*args, **kwargs)
        except KeyError:
            flash('Please log in first...', 'error')
            return redirect(url_for('login'))
    return decorated_function


# Login function
@app.route('/', methods=['GET', 'POST'])
def login():
    """Login page."""
    if request.method=='POST':
    ### Checks database, etc. ###
    return render_template('login.jinja2')


# Example 'restricted' page
@app.route('/download_file')
@logged_in
def download_file():
    """Function used to send files for download to user."""
    fileid = request.args.get('id', 0)
    ### ... ###

After logging in, it needs to return users to the page that took them to the login page.
It also needs to retain things such as the passed variables (i.e. the entire link basically www.example.com/download_file?id=3 )

Does anyone know how to do this?

Thank you for your help :-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

百善笑为先 2024-09-25 06:06:12

我认为标准做法是将用户成功登录后需要重定向到的 URL 附加到登录 URL 的查询字符串的末尾。

您可以将装饰器更改为类似这样的内容(装饰器函数中的冗余也被删除):

def logged_in(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if session.get('logged_in') is not None:
            return f(*args, **kwargs)
        else:
            flash('Please log in first...', 'error')
            next_url = get_current_url() # However you do this in Flask
            login_url = '%s?next=%s' % (url_for('login'), next_url)
            return redirect(login_url)
    return decorated_function

您必须用一些东西来替换 get_current_url(),因为我不知道这是如何完成的烧瓶。

然后,在您的登录处理程序中,当用户成功登录时,您将检查请求中是否有 next 参数,如果有,则将其重定向到该 URL。否则,您将它们重定向到某个默认 URL(我猜通常是 /)。

I think standard practice is to append the URL to which the user needs to be redirected after a successful login to the end of the login URL's querystring.

You'd change your decorator to something like this (with redundancies in your decorator function also removed):

def logged_in(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if session.get('logged_in') is not None:
            return f(*args, **kwargs)
        else:
            flash('Please log in first...', 'error')
            next_url = get_current_url() # However you do this in Flask
            login_url = '%s?next=%s' % (url_for('login'), next_url)
            return redirect(login_url)
    return decorated_function

You'll have to substitute something for get_current_url(), because I don't know how that's done in Flask.

Then, in your login handler, when the user successfully logs in, you check to see if there's a next parameter in the request and, if so, you redirect them to that URL. Otherwise, you redirect them to some default URL (usually /, I guess).

猫卆 2024-09-25 06:06:12

您可以使用查询字符串,只需单击一两次即可保持文件信息完整。 url_for 的优点之一是它将未知参数作为查询字符串传递。因此,无需过多更改注册页面,您可以执行以下操作:

def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if g.user is None:
            return redirect(url_for('register', wantsurl = request.path))
        return f(*args, **kwargs)
    return decorated_function

Here wantsurl 将跟踪用户登陆的 url。如果未注册用户访问 /download/some/file.txtlogin_required 会将您发送至 /register?wantsurl=%2Fdownload%2Fsome%2Ffile.txt 然后,您在注册函数中添加几行:

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'GET':
        if 'wantsurl' in request.args:
            qs = request.args['wantsurl']
            return render_template('register.html', wantsurl=qs)
    if request.method == 'POST':
        if 'wantsurl' in request.form and everything_else_ok:
            return redirect(request.form['wantsurl'])

如果您有名为“wantsurl”且值为 qs 的形式的内容,那么成功注册后会自动重定向到下载。 ,或者您可以使用查询字符串提交表单;这可能只是模板中的一点 if-else。

You could use a query string to keep the file info intact over a click or two. One of the nice things about url_for is how it passes unknown parameters as query strings. So without changing your registration page too much you could do something like this:

def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if g.user is None:
            return redirect(url_for('register', wantsurl = request.path))
        return f(*args, **kwargs)
    return decorated_function

Here wantsurl will keep track of the url the user landed on. If an unregistered user goes to /download/some/file.txt, login_required will send you to /register?wantsurl=%2Fdownload%2Fsome%2Ffile.txt Then you add a couple of lines to your registration function:

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'GET':
        if 'wantsurl' in request.args:
            qs = request.args['wantsurl']
            return render_template('register.html', wantsurl=qs)
    if request.method == 'POST':
        if 'wantsurl' in request.form and everything_else_ok:
            return redirect(request.form['wantsurl'])

That would automatically redirect to the download on successful registration, provided you have something in the form called 'wantsurl' with the value of qs, or you could have your form submit with a query string; that could just be a little if-else in the template.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文