1

I’m using flask to build a web app and I store data in a table called Orders.

I want buyers to have access to a template that will display their order data, like tracking, status, etc. Also I want to give them some actions like the ability to return the order.

For convenience and user experience purposes, I don’t want buyers to register. I want to email them a link that will directly give them access to their order information. So I will create a dynamic route for each order with a token. I also don’t want that token to be really obvious, like order number or something similar, because then anyone can guess an url and return a order that’s not theirs for instance. So it must be unique and a long string of random characters. How should I do it and is this a good approach or bad design?

Thank you!

Pedro Silva
  • 89
  • 1
  • 5
  • Python [Short URL Generator](https://stackoverflow.com/questions/1497504/how-to-make-unique-short-url-with-python). See the first answer. – DarrylG Feb 03 '20 at 13:27

3 Answers3

1

Yes you can do it using Variable Rules from flask, you can put a path in url like this:

@app.route('/user/<path:dinamicPath>')
def show_subpath(dinamicPath):
   if dinamicPath == 'order':
      order = Order.get() #get your orderns from db or files
      return render_template('order.html', order=order)
   elif dinamicPath == 'otherStuff':
      ...
      return

"So I will create a dynamic route for each order with a token. I also don’t want that token to be really obvious, like order number or something similar" you can use a UUID, its supported in Variable Rules too, you can look this link enter link description here

Caio Filus
  • 705
  • 3
  • 17
1

The documentation for uuid.uuid4() says only: "Generate a random UUID", with no guarantees on whether it uses a cryptographic random generator (that is, whether the random values are hard to guess). Even RFC 4122, which specifies UUIDs, says version 4 UUIDs are meant to be generated from "truly-random or pseudo-random numbers", again without any guarantees on cryptographic quality.

For the purposes of generating—

  • hard-to-guess values,
  • that have to be typed in by end users, and
  • serve as bearer credentials whose mere possession grants access to the resource it identifies (a use case explicitly discouraged by RFC 4122 section 6),

a UUID is not appropriate. Instead import the secrets module and generate a random string as follows:secrets.token_hex(16) or even secrets.token_hex(20). Note that unlike uuid, the secrets module is documented to generate cryptographically random values. See also Unique Random Identifiers.

Also you should consider adding some form of authorization, such as confirming email address or the like, if you feel you can do so without burdening users. Also, you should consider the temporary nature of order and tracking information.

Community
  • 1
  • 1
Peter O.
  • 32,158
  • 14
  • 82
  • 96
  • thanks for your answer. That module generates unique tokens? So, I would generate a token, store it in db in an Order Column, email the user with url and when that dynamic route is accessed, I should query the db filtering by the token. I thought about the temporary nature of the information but I'm not sure how to deal with it. I mean, order data might have to be stored for some time for accounting purposes, maybe delete orders after a period of time? – Pedro Silva Feb 03 '20 at 22:09
  • A string generated with `secrets.token_hex(16)` is unique with overwhelming probability (just as a UUID is). Depending on your tolerance to the risk of duplicates, you may want to check the string for uniqueness in your database. I'm only making you generally aware of the temporary nature of order data; I can't answer whether you must delete, retain, or keep the data available in a particular case. – Peter O. Feb 03 '20 at 22:18
  • But uuid and secrets both use os.urandom so no benefit from secrets token_hex, refer https://stackoverflow.com/questions/61638695/what-is-the-difference-between-uuid4-and-secrets-token-bytes-in-python?noredirect=1#comment109033804_61638695 – void May 06 '20 at 16:42
  • @void: Although that may be the case for the current version of `uuid` and `secrets`, `uuid` doesn't _document_ the use of a cryptographic random generator. If you think that's a problem, file an issue on bugs.python.org suggesting better documentation for `uuid` on this matter. – Peter O. May 06 '20 at 17:10
0

Try using UUID's perhaps, for your orders - that can be passed as a query param in your relevant routes. You can create them as:

import uuid

hard_to_guess_string = uuid.uuid4()
another_string = uuid.uuid4()
Sam Chats
  • 2,271
  • 1
  • 12
  • 34