簡體   English   中英

在Elixir Phoenix Absinthe GraphIQL客戶端中實現身份驗證?

[英]implementing authentication in Elixir Phoenix Absinthe GraphIQL client?

我在Absinthe中使用內置的GraphiQL接口。 如下:

  pipeline :browser do
    plug RemoteIp, headers: ~w[x-forwarded-for], proxies: ~w[]
    plug :accepts, ["html", "json"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end

  scope "/graphiql" do
    pipe_through :browser # Use the default browser stack

    forward "/", Absinthe.Plug.GraphiQL,
            schema: ApiWeb.Schema,
            default_headers: {__MODULE__, :graphiql_headers},
            context: %{pubsub: ApiWeb.Endpoint}
  end

  def graphiql_headers(conn) do
    %{
      "X-CSRF-Token" => Plug.CSRFProtection.get_csrf_token(),
    }
  end

我需要最終用戶在接口中插入Authentication: Bearer <JWT> ,然后需要為sub:header打開它,其中包含我的用戶ID,我需要在解析器中使用它。

用戶可以配置自定義標頭,這沒問題。 如果他然后執行GraphSQL查詢,接口將向/ graphiql端點發出POST。 一點上,我想調用一些檢查JWT並檢索用戶信息的插件。

我以為我可以使用default_headers選項,但似乎只在GET請求期間調用。

似乎我需要不同的管道用於GET和POST到/ graphiql端點,我該如何實現呢? 我一定做錯了什么...

請注意,如果我對GET和POST使用相同的管道,則只需訪問瀏覽器中的端點即可檢查JWT,這是我不想要的。

是的,實際上我做了以下事情:

  pipeline :authenticate_on_post_only do
    plug ApiWeb.Plugs.Authenticate, post_only: true
  end

  scope "/graphiql" do
    pipe_through [:browser, :authenticate_on_post_only]

    forward "/", Absinthe.Plug.GraphiQL,
            schema: ApiWeb.GraphQL,
            socket: ApiWeb.GraphQLSocket
  end

結合:

defmodule ApiWeb.Plugs.Authenticate do
  use Plug.Builder
  alias ApiWeb.Helpers.JWT

  plug Joken.Plug, verify: &JWT.verify/0, on_error: &JWT.error/2
  plug ApiWeb.Plugs.Subject
  plug Backend.Plug.Session

  def call(%Plug.Conn{method: "POST"} = conn, opts) do
    conn = super(conn, opts) # calls the above plugs
    put_private(conn, :absinthe, %{context: conn})  # for absinthe (GraphQL), for resolvers to re-use
  end
  def call(conn, opts) do
    if opts[:post_only] do
      conn
    else
      super(conn, opts) # calls the above plugs
    end
  end
end

當然,您可以使用任何自己的身份驗證插件,而不是我列出的那些。

我在同一模塊中也有一個REST API,我使用如下:

  scope "/v1", ApiWeb do
    pipe_through :api

    <my resources here>
  done

api管道定義為:

  pipeline :api do
    plug :put_resp_content_type, "application/json"
    plug :accepts, ["json"]
    plug ApiWeb.Plugs.Authenticate
  end

它將在任何類型的HTTP請求上進行身份驗證。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM