Packages
openmaize
0.6.0
3.0.1
retired
3.0.0
2.9.0
2.8.0
2.7.0
2.6.0
2.5.1
2.5.0
2.4.0
2.3.2
2.3.1
2.3.0
2.2.0
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.2
2.0.1
2.0.0
1.0.1
1.0.0
1.0.0-beta.5
1.0.0-beta.4
1.0.0-beta.3
1.0.0-beta.2
1.0.0-beta.1
1.0.0-beta.0
0.19.3
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.17.2
0.17.1
0.17.0
0.16.2
0.16.1
0.16.0
0.15.1
0.15.0
0.14.0
0.13.0
0.12.0
0.11.1
0.11.0
0.10.2
0.10.1
0.10.0
0.8.1
0.8.0
0.7.5
0.7.4
0.7.2
0.7.1
0.7.0
0.6.7
0.6.6
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.1
0.4.0
Authentication library for Elixir using Plug
Current section
Files
Jump to
Current section
Files
lib/openmaize/plugs/authenticate.ex
defmodule Openmaize.Authenticate do
@moduledoc """
Plug to authenticate users, using Json Web Tokens.
For more information about Json Web Tokens, see the documentation for
the Openmaize.Token module.
This module also sets the current_user variable, which, if you are using
Phoenix, can then be used in your templates. If no token is found, the
current_user is set to nil.
There are two options:
* redirects
* if true, which is the default, redirect on login / logout
* storage
* storage method for the token -- the default is :cookie
* if redirects is set to false, storage is automatically set to nil
## Examples
Call Authenticate without any options:
Plug Openmaize.Authenticate
Call Authenticate and send the token in the response body:
Plug Openmaize.Authenticate, storage: nil
Call Authenticate without redirects:
Plug Openmaize.Authenticate, redirects: false
"""
import Plug.Conn
import Openmaize.Report
alias Openmaize.Token
@behaviour Plug
def init(opts), do: opts
@doc """
This function checks the token, which is either in a cookie or the
request headers and authenticates the user based on the information in
the token.
If the authentication is successful, a map, called `:current_user`,
providing the user information is added to the `assigns` map in the
Plug connection. If there is no token, the `:current_user` is set to nil.
If there is an error, the user is either redirected to the login page
or an error message is sent to the user. The connection is also halted.
"""
def call(%{private: private} = conn, opts) do
if Map.get(private, :openmaize_skip) == true do
conn
else
opts = {Keyword.get(opts, :redirects, true), Keyword.get(opts, :storage, :cookie)}
run(conn, opts)
end
end
defp run(conn, {_, :cookie} = opts) do
conn = fetch_cookies(conn)
Map.get(conn.req_cookies, "access_token") |> check_token(conn, opts)
end
defp run(%{req_headers: headers} = conn, opts) do
get_token(headers) |> Enum.at(0) |> check_token(conn, opts)
end
defp get_token(headers) do
for {k, v} <- headers, k == "authorization" or k == "access-token", do: v
end
defp check_token("Bearer " <> token, conn, opts), do: check_token(token, conn, opts)
defp check_token(token, conn, opts) when is_binary(token) do
case Token.decode(token) do
{:ok, data} -> assign(conn, :current_user, data)
{:error, message} -> authenticate_error(conn, message, opts)
end
end
defp check_token(_, conn, _) do
assign(conn, :current_user, nil)
end
defp authenticate_error(conn, message, {false, _}) do
send_error(conn, 401, message)
end
defp authenticate_error(conn, message, _), do: handle_error(conn, message)
end