Hi friends, How can we get conn object in a different module (in my case resolution function of absinthe) ?
I want to get the ip by conn.remote_ip
property of conn. But I’m not able to get the conn
Show your code. Propably you didn’t use plug
properly. You should use plug
to intercept the conn
or just pass conn
explicitly to your function in the controller’s action.
defmodule MyApp.Schema do
use Absinthe.Schema
import Plug.conn
...
...
...
field :tracking_ip, :string do
arg: params
resolve fn {%{context: %{current_user: current_user}} ->
IO.inspect conn
end
end
I want to fetch the ip form conn
!
import Plug.Conn
would only import the functions inside the Plug.Conn
module, not the conn
struct from a request.
What you probably want to do is create a “context” plug like here where you can add the ip address to the returned context, such that your resolve function would become
resolve fn _, %{context: %{current_user: current_user, remote_ip: remote_ip}} ->
...
end
The context plug would probably look like this
defmodule YourAppName.Web.Context do
@behaviour Plug
import Plug.Conn
def init(opts) do
opts
end
def call(conn, _opts) do
case build_context(conn) do
{:ok, context} ->
put_private(conn, :absinthe, %{context: context})
{:error, reason} ->
conn
|> send_resp(403, reason)
|> halt()
_ ->
conn
|> send_resp(400, "Bad Request")
|> halt()
end
end
# Return the current user context based on the authorization header
# and remote ip address
defp build_context(%{req_readers: req_readers, remote_ip: remote_ip}) do
with "Bearer " <> token <- :proplists.get_value("authorization", req_readers),
{:ok, current_user} <- authorize(token) do
{:ok, %{current_user: current_user, remote_ip: remote_ip}}
end
end
defp authorize(token) do
# ... your auth logic
end
end
Note that remote_ip
might be “wrong” if you are behind a load balancer.
2 Likes