简体   繁体   中英

Passing data from a GET request to a POST request with Python Flask

I Flask, I am building a small web app structured that way:

@app.route("myGet/")
def myGet():
   mySuperLongString = generateRandomSuperLongString()
   return render_template("myTemplate.html",text=mySuperLongString)

@app.route("myPost/")
def myPost():
   answer = request.form['answer']
   if someCondition(mySuperLongString, answer):
      return "you got it!"
   else:
      return "no, it's wrong"

And myTemplate.html contains:

<form method = post class = solution action={{url_for('myPost')}}>
  <dl>
    <dt>
      <text>{{mySuperLongString}}</text>
      <dd><textarea name=answer row=5 col=40></textarea></dd>
      <dd><input type=submit value='your answer'></dd>
    </dt>
  </dl>
</form>

Basically, I don't know how the function myPost can know about mySuperLongString . I tried to pass it in myTemplate.html by adding a name in the <text> field (replacing <text> by <text name=string> ) but Python wouldn't give me access to it. Also I don't want to put mySuperLongString in the url associated with myPost .

So, does someone know how I can pass data between my requests?

You can use a hidden form variable, eg

<input type="hidden" name="superlongstring" value="{{mySuperLongString}}">

But this is a Bad Idea because a clever user can view source and modify that value to whatever they want, potentially breaking your code.

A better idea is to attach it to the user's session, and conveniently Flask provides such a mechanism . To use it, in myGet() add

flask.session['superlongstring'] = mySuperLongString

In myPost() retrieve it using

mySuperLongString  = flask.session['superlongstring']

freespace's answer is to use cookies. This is the easiest way to do it, and will probably work for you. However, it does have some subtle nuances:

  • It does rely on using cookies, which could possibly break the statelessness of the form. If the user opens the form in two tabs, then submits the form using the form in the tab that was opened first, then the form will be sent with the second generated "super long string", not the first. This might be a problem, or it might not.

  • Additionally, a short cookie expiration (or more likely, a browser with cookies disabled) causes this strategy to fail.

Both of these are probably not a large enough problem for you to need another solution, but just in case you do, an alternative is to indeed place the super long string in the form, using the <input type="hidden"> tag...

<form method = post class = solution action={{url_for('myPost')}}>
  <dl>
    <dt>
      <input type="hidden" name="superlongstring" value="{{mySuperLongString}}"></input>
      <dd><textarea name=answer row=5 col=40></textarea></dd>
      <dd><input type=submit value='your answer'></dd>
    </dt>
  </dl>
</form>

As freespace already showed, there is no stopping a smart user from changing the value of "superlongstring". If you want to prevent this, you can use something like the itsdangerous library to help you create a string that the user can tamper with all they want, but your code can easily identify as a "tampered" string. Then, on the server side, you can check for the tampered string and handle it as you wish.

Keep in mind that this will not "encrypt" your "super long string". A smart user would be able to determine what the actual value of the "super long string" is (but then again, they would be able to do that with the cookie method as well).

As an aside, this is exactly how Flask deals with creating cookies from values in the session object so that they cannot be easily tampered with.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM