如果您来自特定的 URL,如何使 Flask 中的 app.route() 仅起作用?

How to make an app.route() in Flask only functional if you are coming from a specific URL?

我正在创建一个项目来学习如何使用 Stripe 并使用注册模板。我与 Stripe 的集成工作正常,我可以成功付款,付款完成后,我被重定向到我的注册模板。

问题是,您应该只有在完成 Stripe 集成后才能访问注册模板,但实际情况是任何手动访问“/register”URL 的人都可以绕过付款阶段并在注册模板中注册自己。

我在这个过程中使用的路线是:

@app.route('/stripe_pay')
def stripe_pay():
    session = stripe.checkout.Session.create(
        payment_method_types=['card'],
        line_items=[{
            'price': '{{ PRICE ID }}',
            'quantity': 1,
        }],
        mode='subscription',
        success_url=url_for('register', _external=True),
        cancel_url=url_for('signup', _external=True),
    )
    return {
        'checkout_session_id': session['id'],
        'checkout_public_key': app.config['STRIPE_PUBLIC_KEY'],
    }

'/register' 路由执行用户数据收集,然后将所有信息记录在数据库中。该过程一切正常。

@app.route('/register')
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        todb = c_personal_info( first_name = form.first_name.data,
                            last_name = form.last_name.data,
                            email = form.email.data,
                            password = form.password.data,
                            subscription='M')
        with db.session.begin():
            db.session.add(todb)
        flash('Thanks for registering! You can now login!', category="success")
        return redirect(url_for('login'))
    return render_template('register.html', form = form)

会话未通过身份验证,因为“/register”模板实际上是您创建登录凭据的地方。

我的问题是如何使“/register”端点只能在您来自“/stripe_pay”端点时访问?我也很想听听你的想法和不同的方法。

研究使用装饰器来处理您的问题。例如,参见 https://flask.palletsprojects.com/en/2.0.x/tutorial/views/

def login_required(view):
    @functools.wraps(view)
    def wrapped_view(**kwargs):
        if g.user is None:
            return redirect(url_for('auth.login'))

        return view(**kwargs)

    return wrapped_view

这段代码将要求用户先登录,然后才能访问任何具有 @login_required 装饰器的页面。

我通过使用“@login_required”装饰器结合“Flask-Login”中的“current_user”模块解决了我的问题。

1 - 作为最后一步,在路由到我要保护的路由之前,我使用“管理员”用户登录。我为此和其他特权访问创建了该用户。

2 - 我用“@login_required”修饰了目标路由,所以我阻止了未登录的用户,然后我使用了“current_user”,条件是只允许“admin”用户继续。任何其他登录用户将被重定向到不同的 URL.