Based on this, I am trying to restrict access to certain APIs based on admin role.
If I provide invalid access_token, the API returns 401 - Not authenticated (Working fine)
If I provide a valid admin user access_token, API returns the expected JSON output. (Working as expected)
However, if I provide a valid non-admin user access_token, API returns the following output.
[error] #PID<0.2419.0> running MyAppWeb.Endpoint (connection #PID<0.2418.0>, stream id 1) terminated
Server: localhost:4000 (http)
Request: GET /api/v1/customers
** (exit) an exception was raised:
** (ArgumentError) flash not fetched, call fetch_flash/2
What is this error due to and how do I gracefully return a proper error code and error message when non-admin access_token is provided for the API?
By default the :api pipeline in phoenix does neither use sessions nor flash messaging. So you want to make sure to now use them in api requests or add the relevant plugs to enable the features.
Hi dimitarvp,
My router pipeline and scope is as follows.
pipeline :admin do
plug MyAppWeb.EnsureRolePlug, :admin
end
scope "/api/v1", MyAppWeb, as: :api_v1 do
pipe_through [:api, :admin]
# API specific to Admin role
resources "/customers", CustomerController, except: [:new, :edit]
end
Hi Lostkobrakai,
Alternatively, I am also using plug MyAppWeb.EnsureRolePlug, :admin inside the controller as well. How do I use within api requests such that I return deferent set of results whether admin or user using the api? Thats my actual need.
Hi dimitarvp,
I have included other plugs mentioned in browser, however I still get the same error.
Here is my new pipeline.
pipeline :admin do
plug MyAppWeb.EnsureRolePlug, :admin
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug Pow.Plug.Session, otp_app: :my_app
end
I have just excluded the following couple of them which seem more specific to browser.
If I move the EnsureRole plug after fetch_flash and fetch_session plug entries, flash not fetched error is gone. However, I get the new error now.
[error] #PID<0.4524.0> running MyAppWeb.Endpoint (connection #PID<0.4488.0>, stream id 2) terminated
Server: localhost:4000 (http)
Request: GET /api/v1/customers
** (exit) an exception was raised:
** (UndefinedFunctionError) function MyAppWeb.Router.Helpers.page_path/2 is undefined or private
Following is the code snippet thats causing the issue.
alias MyAppWeb.Router.Helpers, as: Routes
...
defp maybe_halt(_any, conn) do
conn
|> Controller.put_flash(:error, "Unauthorized access") # Issue with this is resolved.
|> Controller.redirect(to: Routes.page_path(conn, :index)) # This is causing the issue now
# |> put_status(403)
# |> json(%{error: %{code: 403, message: "Forbidden access"}})
|> halt()
end
However, if I use put_status() instead of the error code, it works fine.
Whats the reason why is page_path undefined though I have alias defined for Routes? And how to resolve this issue?
Hi dimitarvp,
Yes, I have a route for page, thats created by default when the project was created. However, we won’t be using this and plan to comment/remove this route.
scope "/", MyAppWeb do
pipe_through :browser
get "/", PageController, :index
end