将Google App Engine实体密钥传递到网页以维护上下文是否安全?

Min*_*ice 3 python google-app-engine entity key google-cloud-datastore

我有一个简单的GAE系统,其中包含Account,Project和Transaction的模型.

我正在使用Django生成一个网页,其中包含属于给定帐户的表中的项目列表,我想创建指向每个项目详细信息页面的链接.我正在生成一个链接,将Project的键转换为字符串,并在链接中包含该链接,以便于查找Project对象.这给出了一个如下所示的链接:

<a href="/project?key=agxkZAB-bnVpY2VrbXRyDDsSBkNvdXBvbhgBDA">My Project Name</a>
Run Code Online (Sandbox Code Playgroud)
  1. 创建这样的链接是否安全?有没有更好的办法?保持背景感觉是一种糟糕的方式.

  2. 键字符串显示在链接页面中并且很难看.有没有办法避免显示它?

谢谢.

Igo*_*nov 6

在GAE文档中,很少有使用相同方法的示例,并且Key使用安全字符来包含在URL中.所以,可能没有问题.

顺便说一句,我更喜欢使用数字ID(obj_key.id()),当我的模型使用数字作为标识符时,只是因为它看起来不那么难看.

  • 如果您需要安全网址,只能由所有者打开,您至少需要添加一个身份验证图层,但不要让网址"难以猜测" (4认同)

Nic*_*son 5

这是否"安全"取决于您的意思,以及您如何实施您的应用程序.让我们退一步,看看究竟是什么存储在Key对象中.拿钥匙,转到shell.appspot.com,然后输入以下内容:

db.Key(your_key)
Run Code Online (Sandbox Code Playgroud)

这将返回如下内容:

datastore_types.Key.from_path(u'TestKind', 1234, _app=u'shell')
Run Code Online (Sandbox Code Playgroud)

如您所见,密钥包含App ID,种类名称,ID或名称(以及任何父实体的种类/ ID对 - 在本例中为none).在这里你什么都不应该特别关注隐藏,所以这里不应该有任何重大的信息泄漏风险.

您提到用户可以猜测其他URL - 这当然是可能的,因为他们可以解码密钥,修改ID或名称,并重新编码密钥.但是,如果您的安全模型依赖于它们而不是猜测其他URL,则可能需要执行以下操作之一:

  1. 重新考虑您应用的安全模型.如果可以避免,您不应该依赖"秘密URL"来获得任何程度的真实安全性.
  2. 使用密钥名称,并将其设置为用户无法猜测的长随机字符串.

最后一个问题是用户可以修改的其他内容.如果通过传递密钥来处理密钥db.get,则用户可以更改类型名称,并使您获取与您预期的不同的实体类型.如果该实体类恰好具有类似命名的字段,那么您可能会对实体执行某些操作(例如从中显示数据),而这些实体并不是您想要的.您可以通过传递密钥来避免这种情况YourModel.get,这将在获取密钥之前检查密钥是否正确.

但是,所有这些都表示,更好的方法是传递密钥ID或名称.您可以通过调用.id()密钥对象(对于ID - .name()如果您正在使用密钥名称)来提取它,并且您可以使用db.Key.from_path('kind_name', id)- 或仅直接获取实体来重建原始密钥YourModel.get_by_id.