Flask/Werkzeug ، كيفية إرجاع الصفحة السابقة بعد تسجيل الدخول

StackOverflow https://stackoverflow.com/questions/3686465

  •  02-10-2019
  •  | 
  •  

سؤال

أنا أستخدم Flask Micro-Framework الذي يعتمد على Werkzeug ، والذي يستخدم 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)

لا أحد يعرف كيفية القيام بذلك؟

شكرا لك على مساعدتك :-)

هل كانت مفيدة؟

المحلول

أعتقد أن الممارسة القياسية هي إلحاق عنوان URL الذي يحتاج المستخدم إلى إعادة توجيهه بعد تسجيل دخول ناجح إلى نهاية QueryString لعنوان 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 الافتراضي (عادة /, ، اعتقد).

نصائح أخرى

يمكنك استخدام سلسلة استعلام للحفاظ على معلومات الملف سليمة فوق نقرة أو اثنين. واحدة من الأشياء الجميلة حول 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

هنا wantsurl سوف يتتبع عنوان URL الذي هبطه المستخدم. إذا ذهب مستخدم غير مسجل إلى /download/some/file.txt, login_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'])

من شأن ذلك إعادة توجيه تلقائي إلى التنزيل على التسجيل الناجح ، شريطة أن يكون لديك شيء في النموذج يسمى "wanturl" مع قيمة qs, ، أو يمكنك إرسال النموذج الخاص بك مع سلسلة استعلام ؛ يمكن أن يكون ذلك قليلاً إذا كان الإخلاء في القالب.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top