- is phoenix has before_request method
- how do i redirect or restrict access to specify route if doesn’t have session :userame (nil) (because if i write session check in every route, it’s very inefficient
thankyou !
thankyou !
No, Plug do not have anything like before_request
, however as Plug is just pipeline in rough form of:
conn
|> Plug1.call(Plug1.init(opts_1))
|> Plug2.call(Plug2.init(opts_2))
# …
|> PlugN.call(PlugN.init(opts_n))
You can just insert new plug before passing it to your controller function, and as Phoenix.Controller
provides similar API to Plug.Builder
you can do:
defmodule ProtectedController do
use Phoenix.Controller
plug(:check_session_username)
def index(conn, params) do
# …
conn
end
def check_session_username(conn, _opts) do
if get_username_from_session(conn) do
conn
else
conn
|> send_resp(:unauthorized, "Login to proceed")
|> halt() # this one is important as this will "brake" processing
end
end
end
but how i define that only in one file, not in every controller ?
Define Plug, ex.:
defmodule CheckSessionUsernamePlug do
@behaviour Plug
import Plug.Conn
def init(opts) do
opts
end
def call(conn, _opts) do
if get_username_from_session(conn) do
conn
else
conn
|> send_resp(:unauthorized, "Login to proceed")
|> halt() # this one is important as this will "brake" processing
end
end
end
And then you can use this within your controllers/router/endpoint like:
plug CheckSessionUsernamePlug
And that is it. Just remember that it will be called for ALL paths that will go through this Plug, so be careful to not lock out session creation.
okay, after using @hauleth solution, this is my before_request-like solution
in lib/web/endpoint.ex
# you will need to check session in CheckSessionPlug, to prevent
# session not fetched error, call `plug :fetch_session` before
# plug CheckSessionPlug
plug :fetch_session
# Before request-like function that check is cookie has logged
# session or not, if not redirect to "/login", this function
# works on all route except /login
plug CheckSessionPlug
plug MyWeebWeb.Router
note must be in correct order, fetch_session -> checksession -> actual router
CheckSessionPlug
module :
defmodule CheckSessionPlug do
use MyweebWeb, :controller
@behaviour Plug
import Plug.Conn
def init(opts) do
opts
end
def call(conn, _opts) do
is_login = conn.request_path =~ "login"
if is_login == false do
# need fetch_session
username = get_session(conn, :username)
if username == nil do
redirect(conn, to: "/login")
end
end
# pass to actual route
conn
end
end