AppEngine的datastore.Get()是否不验证所请求密钥的命名空间?

时间:2014-01-13 19:31:21

标签: google-app-engine go google-cloud-datastore

我在go-appengine中使用带有数据存储区的命名空间,大致如下:

func getThing() *Thing {
  nctx := appengine.Namespace(ctx, "whatever")

  thing := Thing{}
  key, err := datastore.Get(nctx, key, &thing)
  if err != nil {
    return nil, err
  }
  return thing, nil
}

够简单吧?不幸的是,如果事实证明如果nctx的命名空间与密钥不匹配,那么无论如何它都会愉快地获取对象。而AFAICT,没有办法手动获取密钥的“命名空间”字段来手动验证它。这对我们的应用程序很重要,因为我们有来自Web客户端的密钥,在某些边缘情况下可能与错误的命名空间相关联。

OTOH,如果我使用Thing的密钥作为祖先进行查询,数据存储区(适当地)会返回错误,因为祖先的名称空间与名称空间不匹配上下文(形式为query namespace is 'bar' but ancestor namespace is 'foo')。

我是否遗漏了有关数据存储区提取/查询和命名空间的预期约束,或者这听起来像是一个错误?

1 个答案:

答案 0 :(得分:1)

我假设您传递的是编码密钥,而不仅仅是他们的ID?如果使用datastore.NewKey创建密钥,则传递给它的上下文将设置密钥的名称空间(除非还有父项,在这种情况下将使用名称空间)。

就意图而言,此行为等同于python API - 可以在namespace_mananger上设置不同的命名空间时获取从urlsafe字符串创建的密钥,但使用当前设置的命名空间如果您通过仅指定种类和ID来创建密钥。

使用命名空间的getter会很好,所以你至少可以在反序列化后验证...