I’m building a simple plug that receive a token associated to a user, and if the token isn’t present in the params, I halt the request.
Is this a good approach to API authentication? I’m trying to avoid overkill by using Guardian or JWT.
I’m using a Plug, and using simple query params to authorize requests as opposed to something like header tokens. I want my API to be easily testable using normal URL’s and not need something like Postman to actually try it out.
My approach would be exactly that: to use a plug that will try to find a user for the corresponding token and put it into conn.assigns. If not, you can put status :unauthorized and halt the request. This way you can either add it to a pipeline in the router, or use it on each controller separately.
I actually implemented an API like this and so far it’s worked like a charm.
Yep, works great and not confusing to implement. I ended up with this:
defmodule MyApp.Plug.ApiAuthenticate do
import Plug.Conn
def init(default), do: default
def call(conn, _) do
conn = fetch_query_params(conn)
case MyApp.UserQueries.get_by_token(conn.params["authenticationToken"]) do
{:error, message} ->
conn
|> put_status(:unauthorized)
|> Phoenix.Controller.json(%{message: message})
|> halt
{:not_found, message} ->
conn
|> put_status(:unauthorized)
|> Phoenix.Controller.json(%{message: message})
|> halt
user ->
conn
|> assign(:current_user, user)
end
end
end