【问题标题】:How can I generate an unique url for a specific user如何为特定用户生成唯一 url
【发布时间】:2020-05-19 06:04:25
【问题描述】:

我正在使用 Flask 构建一个 Web 应用程序,并将数据存储在一个名为 Orders 的表中。

我希望买家能够访问一个模板,该模板将显示他们的订单数据,例如跟踪、状态等。我还想给他们一些操作,例如退货的能力。

为了方便和用户体验,我不希望买家注册。我想通过电子邮件向他们发送一个链接,该链接可以直接让他们访问他们的订单信息。因此,我将使用令牌为每个订单创建一个动态路由。我也不希望那个标记非常明显,比如订单号或类似的东西,因为这样任何人都可以猜到一个 url 并返回一个不属于他们的订单。所以它必须是唯一的并且是一长串随机字符。我应该怎么做,这是一个好方法还是坏设计?

谢谢!

【问题讨论】:

标签: python authentication flask access-token user-experience


【解决方案1】:

uuid.uuid4() 的文档只说:“生成随机 UUID”,不保证它是否使用加密随机生成器(即随机值是否难以猜测)。甚至指定 UUID 的 RFC 4122 也表示,版本 4 UUID 是由“真正随机或伪随机数”生成的,同样对加密质量没有任何保证。

为了生成——

  • 难以猜测的值,
  • 必须由最终用户输入,并且
  • 作为不记名凭证,仅仅拥有它就可以访问它所标识的资源(RFC 4122 section 6 明确不鼓励的用例),

UUID 不合适。而是导入secrets module 并生成如下随机字符串:secrets.token_hex(16) 甚至secrets.token_hex(20)。请注意,与uuid 不同,secrets 模块被记录为生成加密随机值。另见Unique Random Identifiers

此外,如果您认为可以在不给用户带来负担的情况下添加某种形式的授权,例如确认电子邮件地址等,您也应该考虑这样做。此外,您应该考虑订单和跟踪信息的临时性质。

【讨论】:

  • 感谢您的回答。该模块生成唯一令牌?因此,我将生成一个令牌,将其存储在 db 的 Order 列中,通过 url 向用户发送电子邮件,当访问该动态路由时,我应该通过令牌查询 db 过滤。我考虑过信息的临时性,但我不知道如何处理它。我的意思是,订单数据可能需要存储一段时间以用于会计目的,也许在一段时间后删除订单?
  • 使用secrets.token_hex(16) 生成的字符串以压倒性的概率是唯一的(就像 UUID 一样)。根据您对重复风险的容忍度,您可能需要检查字符串在数据库中的唯一性。我只是让您大致了解订单数据的临时性质;我无法回答您是否必须在特定情况下删除、保留或保持数据可用。
  • 但是 uuid 和 secrets 都使用 os.urandom 所以不能从 secrets token_hex 中受益,参考stackoverflow.com/questions/61638695/…
  • @void:虽然uuidsecrets 的当前版本可能是这种情况,但uuid 没有记录加密随机数的使用发电机。如果您认为这是一个问题,请在 bugs.python.org 上提交问题,建议在此问题上为 uuid 提供更好的文档。
【解决方案2】:

是的,您可以使用烧瓶中的变量规则来做到这一点,您可以像这样在 url 中放置一个路径:

@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

“所以我将使用令牌为每个订单创建一个动态路由。我也不希望该令牌非常明显,例如订单号或类似的东西”您可以使用 UUID,它在变量规则中也受支持,你可以看看这个链接enter link description here

【讨论】:

    【解决方案3】:

    尝试使用 UUID's 来处理您的订单 - 可以在您的相关路线中作为查询参数传递。您可以将它们创建为:

    import uuid
    
    hard_to_guess_string = uuid.uuid4()
    another_string = uuid.uuid4()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-20
      • 1970-01-01
      • 2018-04-29
      • 2010-11-21
      相关资源
      最近更新 更多