将信息从解析器传递到 post-resolution 中间件
Passing information from resolver to post-resolution middleware
我正在尝试将信息从我的解析器函数传递到我的中间件,以便我可以在响应中设置 cookie。
用例是我想生成一个 Oauth2 授权 link,它允许客户端开始与第三方的 Oauth2 流程。我想生成一个 "state" 对象,我可以在响应中将其设置为 cookie。
我试过打电话
%{resolution | context: state}
在解析器中,但不幸的是,它似乎没有传递该状态。
这是我的解析器函数的简化示例
def get_oauth_link(_parent, _args, resolution) do
state = random_string(10)
part_one = "https://github.com/login/oauth/authorize"
part_two = "?client_id=XXX"
part_three = "&redirect_uri=http://localhost:3000/login/callback"
part_four = "&state=" <> state
part_five = "&scope=user:email"
url = part_one <> part_two <> part_three <> part_four <> part_five
# try to add the state to the resolution to
%{resolution | context: state}
{:ok, url}
end
然后在我的架构中
@desc "Get oauth link"
field :oauthlink non_null(:string) do
resolve(&Resolvers.OauthResolver.get_oauth_link/3)
# middleware after resolution to set a cookie with the provided state
middleware fn resolution, _ ->
# Here i want to extract the state generated in
# the resolver and add to the context
IO.inspect(resolution, label: "Inside resolution")
end
end
我希望能够按照此处记录的 "absinthe_before_send" 方法设置 cookie:https://hexdocs.pm/absinthe_plug/Absinthe.Plug.html#module-before-send
最好的方法是什么?上面的方法对我来说似乎很直观,但是状态在 post-resolution 中间件中不可用。
您不能在解析器函数中更改分辨率。
但是,您可以在中间件中更改分辨率。这就是中间件的用途。 post 解析器中间件解析将有一个 value
字段,其中包含解析器函数的结果(没有 :ok
或 :error
原子)。
你可以做的是 return 来自解析器函数的 state
和 url
,然后在你的 post 解析中间件中,从解析中提取状态 value
字段并将分辨率 value
重置为 url。像这样:
def get_oauth_link(_parent, _args, resolution) do
state = random_string(10)
part_one = "https://github.com/login/oauth/authorize"
part_two = "?client_id=XXX"
part_three = "&redirect_uri=http://localhost:3000/login/callback"
part_four = "&state=" <> state
part_five = "&scope=user:email"
url = part_one <> part_two <> part_three <> part_four <> part_five
{:ok, %{url: url, state: state}} # return state and url
end
field :oauthlink, non_null(:string) do
resolve(&Resolvers.OauthResolver.get_oauth_link/3)
middleware fn %{value: %{state: state, url: url}=resolution, _ ->
resolution
|> Map.put(:context, state) # set context using state
|> Map.put(:value, url) # reset value to url
end
end
我认为您不能像现在这样更改分辨率。
老实说,我不明白为什么你不能只使用中间件来设置或不设置。为什么你不能只在中间件上生成它?
但是,我可以找到一种方法。
@desc "Return api version"
field :version, :version_payload do
resolve(fn _, _ -> {:ok, %{version: OnCallAPI.version(), other: "Marcos"}} end)
middleware fn resolution, _ ->
# Here i want to extract the state generated in
# the resolver and add to the context
IO.inspect(resolution, label: "Inside resolution")
end
end
如果您查看控制台,您将在 values
上看到 other
。像这样:
...
private: %{},
root_value: %{},
schema: OnCallAPIWeb.Schema,
source: %{},
state: :resolved,
value: %{other: "Marcos", version: "0.30.0-rc"}
我正在尝试将信息从我的解析器函数传递到我的中间件,以便我可以在响应中设置 cookie。
用例是我想生成一个 Oauth2 授权 link,它允许客户端开始与第三方的 Oauth2 流程。我想生成一个 "state" 对象,我可以在响应中将其设置为 cookie。
我试过打电话
%{resolution | context: state}
在解析器中,但不幸的是,它似乎没有传递该状态。
这是我的解析器函数的简化示例
def get_oauth_link(_parent, _args, resolution) do
state = random_string(10)
part_one = "https://github.com/login/oauth/authorize"
part_two = "?client_id=XXX"
part_three = "&redirect_uri=http://localhost:3000/login/callback"
part_four = "&state=" <> state
part_five = "&scope=user:email"
url = part_one <> part_two <> part_three <> part_four <> part_five
# try to add the state to the resolution to
%{resolution | context: state}
{:ok, url}
end
然后在我的架构中
@desc "Get oauth link"
field :oauthlink non_null(:string) do
resolve(&Resolvers.OauthResolver.get_oauth_link/3)
# middleware after resolution to set a cookie with the provided state
middleware fn resolution, _ ->
# Here i want to extract the state generated in
# the resolver and add to the context
IO.inspect(resolution, label: "Inside resolution")
end
end
我希望能够按照此处记录的 "absinthe_before_send" 方法设置 cookie:https://hexdocs.pm/absinthe_plug/Absinthe.Plug.html#module-before-send
最好的方法是什么?上面的方法对我来说似乎很直观,但是状态在 post-resolution 中间件中不可用。
您不能在解析器函数中更改分辨率。
但是,您可以在中间件中更改分辨率。这就是中间件的用途。 post 解析器中间件解析将有一个 value
字段,其中包含解析器函数的结果(没有 :ok
或 :error
原子)。
你可以做的是 return 来自解析器函数的 state
和 url
,然后在你的 post 解析中间件中,从解析中提取状态 value
字段并将分辨率 value
重置为 url。像这样:
def get_oauth_link(_parent, _args, resolution) do
state = random_string(10)
part_one = "https://github.com/login/oauth/authorize"
part_two = "?client_id=XXX"
part_three = "&redirect_uri=http://localhost:3000/login/callback"
part_four = "&state=" <> state
part_five = "&scope=user:email"
url = part_one <> part_two <> part_three <> part_four <> part_five
{:ok, %{url: url, state: state}} # return state and url
end
field :oauthlink, non_null(:string) do
resolve(&Resolvers.OauthResolver.get_oauth_link/3)
middleware fn %{value: %{state: state, url: url}=resolution, _ ->
resolution
|> Map.put(:context, state) # set context using state
|> Map.put(:value, url) # reset value to url
end
end
我认为您不能像现在这样更改分辨率。
老实说,我不明白为什么你不能只使用中间件来设置或不设置。为什么你不能只在中间件上生成它?
但是,我可以找到一种方法。
@desc "Return api version"
field :version, :version_payload do
resolve(fn _, _ -> {:ok, %{version: OnCallAPI.version(), other: "Marcos"}} end)
middleware fn resolution, _ ->
# Here i want to extract the state generated in
# the resolver and add to the context
IO.inspect(resolution, label: "Inside resolution")
end
end
如果您查看控制台,您将在 values
上看到 other
。像这样:
...
private: %{},
root_value: %{},
schema: OnCallAPIWeb.Schema,
source: %{},
state: :resolved,
value: %{other: "Marcos", version: "0.30.0-rc"}