25

Pythonを使用するWerkzeugをベースにしたFlaskマイクロフレームワークを使用しています。

制限された各ページの前に、ユーザーがログインしていることを確認するデコレータがあります。現在、ログインしていない場合は、次のようにログインページに戻ります。

# 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)

誰かがこれを行う方法を知っていますか?

ご協力ありがとうございました :-)

4

2 に答える 2

25

標準的な方法は、ログインが成功した後にユーザーがリダイレクトする必要のある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()Flaskでどのように行われるのかわからないため、の代わりに何かを使用する必要があります。

次に、ログインハンドラーで、ユーザーが正常にログインしたらnext、リクエストにパラメーターがあるかどうかを確認し、ある場合は、そのURLにリダイレクトします。それ以外の場合は、デフォルトのURLにリダイレクトします(通常/、私は推測します)。

于 2010-09-10T16:48:01.750 に答える
12

クエリ文字列を使用して、1〜2回クリックしてもファイル情報をそのまま維持できます。良い点の1つは、不明なパラメータをクエリ文字列として渡す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.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。または、クエリ文字列を使用してフォームを送信することもできます。テンプレートの場合は、それ以外の場合は少しだけかもしれません。

于 2010-09-11T04:57:56.380 に答える