Skip to content

Instantly share code, notes, and snippets.

@mprymek
Last active November 25, 2015 21:29
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save mprymek/0fe6bb614c59e9b788fd to your computer and use it in GitHub Desktop.
Save mprymek/0fe6bb614c59e9b788fd to your computer and use it in GitHub Desktop.
# Simple Phoenix authentication plug
#
# - based on Plug's session store
# - redirects unauthenticated requests to login page "/login/<request url>"
# - /static/... requests are not authenticated
# - authentication is valid as long as session is valid (you can change this behaviour easily)
# Because we need session to be fetched BEFORE this plug, we must put this to router.ex:
#----------------------------
# copied from https://github.com/phoenixframework/phoenix/blob/master/lib/phoenix/router.ex
key = Phoenix.Config.router!(__MODULE__, [:session_key])
secret = Phoenix.Config.router!(__MODULE__, [:session_secret])
plug Plug.Session, store: :cookie, key: key, secret: secret
plug Phoenix.Plugs.SessionFetcher
# auth plug now
plug WebApp.Plugs.Auth, []
# here put your other plugs...
#----------------------------
# Auth plug code:
#----------------------------
defmodule WebApp.Plugs.Auth do
require Logger
def init(opts), do: opts
def call(conn, _opts) do
cond do
skip?(conn.path_info) ->
conn
authenticated?(conn) ->
conn
true ->
Logger.debug "AUTH for #{inspect conn.path_info}"
url = "/#{Enum.join(conn.path_info,"/")}"
Phoenix.Controller.Connection.redirect(conn,"/login#{url}")
Phoenix.Controller.Connection.halt!(conn)
end
end
defp skip?(["static"|_]), do: true
defp skip?(["login"|_]), do: true
#
# you can insert any unauthenticated pages here...
#
defp skip?(_), do: false
def authenticated?(conn) do
# BEWARE!
# User is authenticated as long as session is valid!
# You probably want to check if user still exists and is authorized here.
Plug.Conn.get_session(conn, :user) != nil
end
end
#----------------------------
# Login page in router.ex:
#----------------------------
get "/login/*src", WebApp.LoginController, :login
post "/login/*src", WebApp.LoginController, :login_post
get "/logout", WebApp.LoginController, :logout
#----------------------------
# Login page controller:
#----------------------------
defmodule WebApp.LoginController do
use Phoenix.Controller
def login(conn, _, messages\\[]) do
if WebApp.Plugs.Auth.authenticated?(conn) do
# already logged in
redirect conn, "/#{conn.params["src"]}"
else
render conn, "login", [messages: messages]
end
end
def login_post(conn, _) do
passwd = conn.params["password"]
user = conn.params["username"]
case WebApp.Auth.auth(user,passwd) do
nil ->
login(conn,[{:error,"Login failed."}])
group ->
conn = conn
|> Plug.Conn.put_session(:user, String.to_atom(user))
|> Plug.Conn.put_session(:group, group)
redirect conn, "/#{conn.params["src"]}"
end
end
def logout(conn, _) do
conn = conn
|> Plug.Conn.delete_session(:user)
|> Plug.Conn.delete_session(:group)
redirect conn, "/login"
end
end
#----------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment