Внутренний редирект в Flask

Короче:

Только используя микро-фреймворк Flask (и его зависимости), можем ли мы выполнить внутреннее перенаправление с одного маршрута на другой?

Например:

  1. Пользователь отправляет регистрационную форму (оба username а также password) чтобы @app.route('/register', methods=['POST'])
  2. Если регистрация прошла успешно, Flask внутренне выполняет HTTP POST для @app.route('/login', methods['POST']) прохождение username а также password
  3. Обработка и вход в систему пользователя

Подробности:

Я строю REST API с использованием Flask и расширения Flask-JWT. Конкретнее я реализую логин и регистрацию.

Логин работает отлично и возвращает объект JSON с токеном.

Ниже мой (логин) обработчик аутентификации (т.е. /auth (Запрос POST) - правило URL-адреса проверки подлинности Flask-JWT по умолчанию:

@jwt.authentication_handler
def authenticate(username, password):
    user = User.query.filter_by(username=username).first()
    if user and user.verify_password(password):
        return user
    return None

Успешный вход в систему возвращает:

{
  "token": "<jwt-token>"
}

Ниже мой маршрут регистрации:

@app.route('/register', methods=['PUT'])
def register():
    username = request.form.get('username')
    password = request.form.get('password')
    if username is None or password is None:
        abort(400)  # missing parameters

    user = User.query.filter_by(username=username).first()
    if user:
        abort(400)  # user exists
    else:
        user = User(user=user)
        user.hash_password(password)
        db.session.add(user)
        db.session.commit()

        # How do we generate a token?
        # Perform an internal redirect to the login route?

    return jsonify({'token': <jwt-token>}), 201

1 ответ

Решение

Вы должны использовать шаблон Post-Redirect-Get.

from flask import Flask, redirect, request, render_template
app = Flask("the_flask_module")

@app.route('/', methods=["GET", "POST"])
def post_redirect_get():
    if request.method == "GET":
        return render_template("post_redirect_get.html")
    else:
        # Use said data.
        return redirect("target", code=303)

@app.route("/target")
def target():
    return "I'm the redirected function"

app.run(host="0.0.0.0", port=5001)

И если вы хотите передать данные в целевую функцию (например, этот токен), вы можете использовать объект сеанса для его хранения.

Так что это сломало бы что-то вроде

@app.route('/register', methods=['PUT'])
def register():
    username = request.form.get('username')
    password = request.form.get('password')
    if username is None or password is None:
        abort(400)  # missing parameters

    user = User.query.filter_by(username=username).first()
    if user:
        abort(400)  # user exists
    else:
        user = User(user=user)
        user.hash_password(password)
        db.session.add(user)
        db.session.commit()

        # How do we generate a token?
        redirect("login_success", code=307)

@app.route("login_success", methods=["GET", "POST"])
@jwt_required()
def login_success():
    return "Redirected Success!"

Изменить: я не использовал Flask-JWT раньше и не знал о требованиях к должности. Но вы можете сказать Flask о перенаправлении с использованием текущего метода (а не запроса get), передав функцию перенаправления code=307 ,, Надеюсь, это решит вашу расширенную проблему.

Другие вопросы по тегам