AppEngine的datastore.Get()方法是否不验证请求键的命名空间?

huangapple go评论69阅读模式
英文:

Does AppEngine's datastore.Get() not verify the namespace of the requested key?

问题

我正在使用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的命名空间与键的命名空间不匹配,它仍然会快乐地获取对象。据我所知,没有办法手动访问键的"namespace"字段来手动验证它。对我们的应用程序很重要,因为我们的键来自Web客户端,在某些边缘情况下可能与错误的命名空间相关联。

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

我是否对数据存储的获取/查询和命名空间的预期约束有所误解,还是这听起来像是一个错误?

英文:

I'm using namespaces with the datastore in go-appengine, roughly as follows:

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
}

Simple enough, right? Unfortunately, if it turns out that if nctx's namespace doesn't match the key's, it happily fetches the object anyway. And AFAICT, there's no way to manually get at the key's 'namespace' field to verify it manually. This matters for our app, because we have keys coming from a web client, which can in some edge cases be associated with the wrong namespace.

OTOH, if I do a query using Thing's key as an ancestor, the datastore (appropriately) returns an error because of the namespace mismatch between the ancestor's namespace and that of the context (of the form query namespace is 'bar' but ancestor namespace is 'foo').

Am I missing something about the intended constraints on datastore fetches/queries and namespaces, or does this just sound like a bug?

答案1

得分: 1

我假设你传递的是编码后的键,而不仅仅是它们的ID?如果你使用datastore.NewKey创建键,那么传递给它的上下文将设置键的命名空间(除非还有一个父键,在这种情况下将使用它的命名空间)。

就意图而言,这种行为等同于Python API - 从urlsafe字符串创建的键可以在设置了不同命名空间的namespace_mananger上获取,但如果你只指定了种类和ID来创建键,则使用当前设置的命名空间。

不过,有一个获取命名空间的方法会很好,这样你至少可以在反序列化后进行验证...

英文:

I assume you're passing around encoded keys, rather than just their IDs? If you create the key using datastore.NewKey then the context passed to that will set the namespace of the key (unless there's also a parent, in which case its namespace will be used).

With respect to the intention, this behaviour is equivalent to the python API - a key created from an urlsafe string can be fetched while a different namespace is set on the namespace_mananger, but the currently-set namespace is used if you create a key by specifying just the kind and id.

Having a getter for the namespace would be good though, so you could at least verify after unserializing...

huangapple
  • 本文由 发表于 2014年1月14日 03:31:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/21099759.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定