【问题标题】:Flask POST Redirect: Parameters showing up in address barFlask POST Redirect:地址栏中显示的参数
【发布时间】:2020-08-11 14:44:40
【问题描述】:

设置

  1. Flask 网络应用程序。
  2. 用户导航到多个页面之一 [例如game page (localhost:5000/game) 或 players page (localhost:5000/players)] 通过在表单中​​带有 GAME_ID 的 post 请求。 GAME_ID 用于获取更多详细信息并呈现页面。

目标

  1. 当未经身份验证的用户向/game 发出post 请求时,将他们重定向到/login 页面,但在会话中保留端点(game)和GAME_ID,以便成功登录后,我可以将他们发送回他们正在访问的页面。我的方法是进行 307 重定向。

方法(基于thisthis):

在 application.py 中

@login_manager.unauthorized_handler
def intercept_unauthorized():
    <Set NEXT_PAGE_FOR_REDIRECT and GAME_ID_FOR_REDIRECT into the session>
    return redirect(url_for('login'))

@application.route("/login", methods=['GET', 'POST'])
def login():
    #User sees the login page
    if request.method=='GET':
      <show the login page>
    
    #User has submitted username and password on the login page
    elif request.method=='POST':
      <authentication code here>
      if validUser:
          #Get the page the user was trying to access e.g. 'game'
          nextPage = session.get('NEXT_PAGE_FOR_REDIRECT')
          session.pop('NEXT_PAGE_FOR_REDIRECT')
          gameID = session.get('GAME_ID_FOR_REDIRECT')        
          session.pop('GAME_ID_FOR_REDIRECT')

          return redirect(url_for(next_page, gameID=gameID), code=307)

@application.route("/game", methods=['POST'])
@login_required
def game():
    if 'gameID' in request.form:
        render_template('game.html', gameID=request.form['gameID'])

问题

  1. 我可以重定向到/game,其中request.method 是POST。但是request.form中的数据是login页面提交的数据,即用户名和密码。
  2. 我可以访问我在url_for 行中设置的gameID,但它是在request.args 中发送的(并且在浏览器的地址栏中可见),而不是通过request.form

问题

  1. 我使用重定向的方法是否正确?
  2. 如何修改发送至/game 的表单,以便将gameID 添加到其中?

【问题讨论】:

    标签: python flask


    【解决方案1】:

    发件人:https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307

    HTTP 307 临时重定向重定向状态响应代码指示 请求的资源已暂时移至 URL 由 Location 标头给出。

    重用原始请求的方法和主体来执行 重定向的请求。在您希望使用的方法的情况下 改为 GET,请改用 303 See Other。这在您使用时很有用 想对不是上传的 PUT 方法给出答案 资源,但是一条确认消息(例如“您已成功上传 XYZ")。

    307 和 302 之间的唯一区别是 307 保证 重定向时方法和正文不会改变 已提出请求。

    所以,原来的request.form 被保留了。您可以只使用 session 来显示隐藏的 ID,例如:

    @application.route("/game", methods=['POST'])
    @login_required
    def game():
        gameID = session.get('GAME_ID_FOR_REDIRECT')        
        session.pop('GAME_ID_FOR_REDIRECT')
        render_template('game.html', gameID=gameID )
    

    当然,您必须从 login() 中删除 pop()

    【讨论】:

    • 对不起,我没有在我的问题中提到这一点。我尝试过强制 POST 的 _method 方法,但它仍然将 gameID 作为查询参数发送。我想避免在 UI 上暴露 gameID,因此只想在 /game 页面上使用 POST。您给出的前两个建议都会导致游戏 ID(例如 123)在地址栏中可见(作为 /game/123 或 game?gameID=123)。
    • 另外,我不明白您回复的两个要素。 1.“想要发送 GET”login 中重定向到\game 的请求也是一个 POST,它甚至不应该尝试创建一个 GET,对吧?所以我不明白关于 switching 到 POST 和丢失参数的部分。
    • 2.您说端点无法解析gameID。但如果是 POST 请求,其中 gameID 将包含在 request.form 中,我不需要将 gameID 指定为端点的一部分,对吗?我需要做的就是从request.form 阅读它。
    • 你是对的。我编辑了。不知道307保留了原来的身体和方法。
    • 也许不pop()?我能想到的唯一其他解决方案是将gameID 添加为login() 中的隐藏字段。然后,它将是形式。或者在 Flash 之外构建一个重定向,您可以在其中构建有效负载。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-28
    • 1970-01-01
    • 1970-01-01
    • 2019-07-07
    • 2013-05-21
    • 2018-06-01
    相关资源
    最近更新 更多