【问题标题】:Internal Redirect in FlaskFlask 中的内部重定向
【发布时间】:2015-12-08 15:21:08
【问题描述】:

简而言之:

通过仅使用Flask micro-framework(及其依赖项),我们可以执行从一条路由到另一条路由的内部重定向

例如:

  1. 用户将注册表单(usernamepassword)提交给@app.route('/register', methods=['POST'])
  2. 如果注册成功,Flask 内部会通过usernamepassword@app.route('/login', methods['POST']) 发送HTTP POST
  3. 处理并登录用户

详情:

我正在使用FlaskFlask-JWT 扩展构建一个REST API。更具体地说,我正在实现登录和注册。

登录完美运行并返回带有令牌的 JSON 对象。

以下是我的(登录)身份验证处理程序(即/auth(POST 请求)-默认 Flask-JWT 身份验证 URL 规则):

@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

【问题讨论】:

  • 我不认为您可以使用帖子数据进行重定向...否则您可能只想查看 flask.redirect ...
  • 我认为您所说的“内部重定向”是指通过路由表从 register() 函数调用登录功能,方法是设置一个虚假的外部请求。我不会回答 >that

标签: python flask registration flask-jwt


【解决方案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)

And if you want to pass data to the target function (like that token) you can use the session object to store it

所以这会分解像

这样的东西
@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,也不知道 post 的要求。但是你可以告诉 Flask 使用passing the redirect function code=307. 使用的当前方法(而不是 get 请求)进行重定向。希望这可以解决您的扩展问题。

【讨论】:

  • 它完美地回答了我的简短问题。但不幸的是,它在 Flask-JWT 的上下文中不起作用,因为该扩展正在处理 POST 路由中的身份验证响应(或者至少我无法使其与此扩展一起使用)
  • 我不同意这个答案解决了“我们可以执行从一个路由到另一个路由的内部重定向吗?”的问题,我认为这显然意味着在中间不向客户端提供响应。您的代码确实会向客户端返回响应。您的代码当然是标准/最佳方式,我相信您知道原因:防止重复提交表单 [Grinberg, Miguel。 Flask Web 开发:使用 Python 开发 Web 应用程序(第 44 页)。奥莱利媒体。 Kindle版。 ] 术语“内部重定向”存在很多混淆。
  • @CraigHicks 这当然是一个有效的批评。如果您有办法在没有客户端响应的情况下进行重定向(不会破坏 SSL 安全性、DNSec 或需要特殊的 javascript 来重新加载新资源),我当然会全力以赴。
猜你喜欢
  • 2021-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-25
  • 1970-01-01
  • 2012-12-29
  • 2014-02-23
相关资源
最近更新 更多