定义并非所有用户都可以访问的字段的正确方法是什么?
例如,普通用户可以查询用户并找出其他用户的句柄,但是只有管理员用户才能找到其电子邮件地址。用户类型将其定义为字段,但可能无法访问。一般用户可以看到的类型是否应该单独设置?您将如何定义它?
抱歉,如果不清楚,我只是不掌握词汇。
编辑: 警告: Graphql文档不同意这种方法。请谨慎使用。无论何时需要私有字段,都必须包括适当的中间件。
在中间件中使用苦艾酒。
这是一些代码。在此示例中,经过身份验证的用户可以看到电子邮件地址。匿名用户不能。您可以调整逻辑以要求所需的任何权限。
defmodule MySite.Middleware.RequireAuthenticated do @behaviour Absinthe.Middleware @moduledoc """ Middleware to require authenticated user """ def call(resolution, config) do case resolution.context do %{current_user: _} -> resolution _ -> Absinthe.Resolution.put_result(resolution, {:error, "unauthenticated"}) end end end
然后定义对象:
object :user do field :id, :id field :username, :string field :email, :string do middleware MySite.Middleware.RequireAuthenticated middleware Absinthe.Middleware.MapGet, :email end end
因此,我们的现场电子邮件受RequireAuthenticated中间件保护。但是根据上面的链接
中间件/ 3的一种用法是在字段上设置默认的中间件,以替换default_resolver宏。
通过在字段上使用middleware / 2宏,也会发生这种情况。这就是为什么我们还需要添加
middleware Absinthe.Middleware.MapGet, :email
到现场的中间件列表。
最后,当我们执行查询时
query { user(id: 1){ username email id } }
我们得到的响应包含填充的开放字段和无效的受保护字段
{ "errors": [ { "message": "In field \"email\": unauthenticated", "locations": [ { "line": 4, "column": 0 } ] } ], "data": { "user": { "username": "MyAwesomeUsername", "id": "1", "email": null } } }
您还可以使用Middleware / 3回调,这样您的对象就不会太冗长
def middleware(middleware, %{identifier: :email} = field, _object) do [MySite.Middleware.RequireAuthenticated] ++ [{Absinthe.Middleware.MapGet, :email}] ++ middleware end
通过创造性地使用__using __ / 1回调,您可以从主模式文件中获得大量此类功能。