Python 将Google应用程序引擎实体密钥传递到网页以维护上下文安全吗?
我有一个简单的GAE系统,它包含帐户、项目和事务的模型 我正在使用Django生成一个网页,该网页在一个表中包含属于给定帐户的项目列表,我希望创建一个指向每个项目详细信息页面的链接。我正在生成一个链接,将项目的键转换为字符串,并将其包含在链接中,以便于查找项目对象。这将提供一个如下所示的链接:Python 将Google应用程序引擎实体密钥传递到网页以维护上下文安全吗?,python,google-app-engine,entity,google-cloud-datastore,key,Python,Google App Engine,Entity,Google Cloud Datastore,Key,我有一个简单的GAE系统,它包含帐户、项目和事务的模型 我正在使用Django生成一个网页,该网页在一个表中包含属于给定帐户的项目列表,我希望创建一个指向每个项目详细信息页面的链接。我正在生成一个链接,将项目的键转换为字符串,并将其包含在链接中,以便于查找项目对象。这将提供一个如下所示的链接: <a href="/project?key=agxkZAB-bnVpY2VrbXRyDDsSBkNvdXBvbhgBDA">My Project Name</a> 创建这样的
<a href="/project?key=agxkZAB-bnVpY2VrbXRyDDsSBkNvdXBvbhgBDA">My Project Name</a>
谢谢。在GAE文档中,很少有使用相同方法的示例,而且关键是在URL中使用安全的字符。所以,可能没有问题
顺便说一句,当我的模型使用数字作为标识符时,我更喜欢使用数字ID(
obj_key.ID()
),因为它看起来不那么难看。这是否“安全”取决于你的意思,以及你如何实现你的应用程序。让我们退后一点,看看键对象中到底存储了什么。带上钥匙,转到shell.appspot.com
,然后输入以下内容:
db.Key(your_key)
datastore_types.Key.from_path(u'TestKind', 1234, _app=u'shell')
这将返回如下内容:
db.Key(your_key)
datastore_types.Key.from_path(u'TestKind', 1234, _app=u'shell')
如您所见,该键包含应用程序ID、种类名称和ID或名称(以及任何父实体的种类/ID对-在本例中为无)。这里没有什么你应该特别关注的隐藏,所以这里不应该有任何重大的信息泄漏风险
您提到用户可能会猜测其他URL,这当然是可能的,因为他们可以解码密钥,修改ID或名称,并重新编码密钥。但是,如果您的安全模型依赖于它们,而不是猜测其他URL,那么您可能需要做以下几件事之一:
尽管如此,更好的方法是传递密钥ID或名称。您可以通过调用key对象上的
.id()
(对于id-.name()
,如果您使用的是key name),来提取这个值,并且您可以使用db.key.从\u path('kind\u name',id)
)重构原始密钥,或者直接使用您的模型来获取实体。通过\u id
获取\u它们不仅仅是增加;我的数据存储中只有10个条目,我已经达到7001。
只要有某种形式的保护,让用户不能简单地猜测,就没有理由不这么做。在做了更多的研究之后,我想我现在可以回答我自己的问题了。我想知道使用GAE密钥或ID是否本质上是不安全的 事实上,如果没有一些额外的代码,这是不安全的,因为用户可以修改返回网页中的URL或访问他们手动构建的URL。这可能让经过身份验证的用户只需更改URL中的密钥Id即可编辑其他用户的数据 因此,对于您允许访问的每个资源,您需要确保当前经过身份验证的用户有权以他们尝试的方式访问它
这涉及到为每个操作编写额外的查询,因为似乎没有一种内置的方式可以说“用户只能访问他们拥有的对象”。我知道这是一篇老文章,但我想澄清一件事。有时你需要使用钥匙
当您有一个具有@Parent关系的实体时,您无法通过其ID获取它,您需要使用整个键从数据存储中获取它。在这些情况下,如果要检索实体,您需要始终使用密钥。谢谢您的回复。我关心的不是键是否是URL安全的,而是用户根据看到的其他URL猜测其他URL。数字ID是简单的递增整数,似乎更容易破解。如果你需要安全的url,只能由所有者打开,你至少需要添加一个身份验证层,但使用数字ID时不要让url“难以猜测”+1。我一直在使用密钥,数字ID看起来更漂亮。我确实有一个使用Google登录的身份验证层,但你需要的不仅仅是授权。您需要确保当前用户可以访问每个资源。这需要编写很多额外的代码,但这是确保安全性所必需的。我只是希望通过设置数据库属性或其他什么来实现更自动化。这取决于您使用的框架,但我不想用任何标准和自动的方法来保护url。也许你必须自己去实现它