首页 > 解决方案 > Absinthe - 如何将_session 放入解析器函数中?

问题描述

我正在使用苦艾酒并且有一个突变的迹象。当用户通过有效凭据发送时,我想通过在响应中设置会话 cookie put_session

我面临的问题是我无法conn从解析器函数中访问。这告诉我,我不应该从解析器中更新连接的属性。

用苦艾酒可以做到这一点吗?有哪些替代解决方案?

标签: graphqlelixirsession-cookiesphoenix-frameworkabsinthe

解决方案


看起来一种解决方案是:

  1. 在解析器中,正常解析 an{:ok, _}或 an{:error, _}
  2. 在解析器之后添加中间件以从步骤 1 返回的模式匹配resolution.value并更新 GraphQL 上下文
  3. 使用 Absinthe 的before_sendput_session功能(在发送响应之前可以访问 GraphQL 上下文和连接

代码示例

突变:

mutation do
  @desc "Authenticate a user."
  field :login, :user do
    arg(:email, non_null(:string))
    arg(:password, non_null(:string))
    resolve(&Resolvers.Accounts.signin/3)

    middleware(fn resolution, _ ->
      case resolution.value do
        %{user: user, auth_token: auth_token} ->
          Map.update!(
            resolution,
            :context,
            &Map.merge(&1, %{auth_token: auth_token, user: user})
          )

        _ ->
          resolution
      end
    end)
  end
end

解析器:

defmodule AppWeb.Resolvers.Accounts do
  alias App.Accounts

  def signin(_, %{email: email, password: password}, _) do
    if user = Accounts.get_user_by_email_and_password(email, password) do
      auth_token = Accounts.generate_user_session_token(user)
      {:ok, %{user: user, auth_token: auth_token}}
    else
      {:error, "Invalid credentials."}
    end
  end
end

路由器:

defmodule AppWeb.Router do
  use AppWeb, :router

  pipeline :api do
    plug(:accepts, ["json"])
    plug(:fetch_session)
  end

  scope "/" do
    pipe_through(:api)

    forward("/api", Absinthe.Plug,
      schema: AppWeb.Schema,
      before_send: {__MODULE__, :absinthe_before_send}
    )

    forward("/graphiql", Absinthe.Plug.GraphiQL,
      schema: AppWeb.Schema,
      before_send: {__MODULE__, :absinthe_before_send}
    )
  end

  def absinthe_before_send(conn, %Absinthe.Blueprint{} = blueprint) do
    if auth_token = blueprint.execution.context[:auth_token] do
      put_session(conn, :auth_token, auth_token)
    else
      conn
    end
  end

  def absinthe_before_send(conn, _) do
    conn
  end
end

推荐阅读