Hi folks,
This is my first Phoenix/Web application .
My phoenix app uses an authentication scheme based on JWTs. I need to modify the authentication code base to support another authentication method which I’ll call “x-scheme”. For backward compatibility, I need to support the JWT method as well. Thinking out loud, I need a disjunction (logical or) of both schemes similar to the code snippet below:
pipeline :authenticate do
plug(:jwt_auth) or plug(:x_scheme_auth)
end
What is the best way to address this in Elixir/Phoenix? Is this even a good idea? Any help is much appreciated.
pipeline :authenticate do
plug :authed
end
def authed(conn, opts) do
case jwt_auth(conn, opts) do
%Plug.Conn{halted: true} -> x_scheme_auth(conn, opts)
conn -> conn
end
end
Thanks for reaching out! I have not used :halted in implementing the jwt_auth/2method; could you please explain its usage? I did not understand its documentation.
It’s a field that gets set by plug when you (or the underlying auth library) calls Plug.halt, which is happening when the code figures that its job of the plug is not done / has failed (I’d guess in the case of invalid or expired JWT auth token).
EDIT: oops, I posted literal seconds after you. I’d say yes, try that, it should work.
When halt/1 is called on a plug, it just means that the plug functions that were registered to be called further in the “pipeline” would not be called.
Mix.install [:plug]
defmodule Endpoint do
use Plug.Builder
def print(conn, opts) do
IO.puts(Keyword.fetch!(opts, :message))
conn
end
def auth(conn, opts) do
if opts[:pass] do
conn
else
conn |> Plug.Conn.resp(401, "not authed") |> halt()
end
end
plug :print, message: "1"
plug :auth, pass: false
plug :print, message: "2"
end
Endpoint.call(%Plug.Conn{}, [])
prints 1
I assumed halt/1 was called in jwt_auth/2 and x_scheme_auth/2 when the authentication failed.