mirror of
https://github.com/kevin-DL/phoenix_api_template.git
synced 2026-01-11 18:54:33 +00:00
hopefully done
This commit is contained in:
@@ -5,3 +5,7 @@ end
|
||||
defmodule PhoenixApiTemplateWeb.Auth.ErrorResponse.Forbidden do
|
||||
defexception message: "Forbidden", plug_status: 403
|
||||
end
|
||||
|
||||
defmodule PhoenixApiTemplateWeb.Auth.ErrorResponse.NotFound do
|
||||
defexception message: "Not Found", plug_status: 404
|
||||
end
|
||||
|
||||
@@ -29,18 +29,58 @@ defmodule PhoenixApiTemplateWeb.Auth.Guardian do
|
||||
|
||||
user ->
|
||||
case validate_password(password, user.hashed_password) do
|
||||
true -> create_token(user)
|
||||
true -> create_token(user, :access)
|
||||
false -> {:error, :unauthorized}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def authenticate(token) do
|
||||
with {:ok, claims} <- decode_and_verify(token),
|
||||
{:ok, user} <- resource_from_claims(claims),
|
||||
{:ok, _old, {new_token, _claims}} <- refresh(token) do
|
||||
{:ok, user, new_token}
|
||||
end
|
||||
end
|
||||
|
||||
defp validate_password(password, hashed_password) do
|
||||
Bcrypt.verify_pass(password, hashed_password)
|
||||
end
|
||||
|
||||
defp create_token(user) do
|
||||
{:ok, token, _claims} = encode_and_sign(user)
|
||||
defp create_token(user, type) do
|
||||
{:ok, token, _claims} = encode_and_sign(user, %{}, token_options(type))
|
||||
{:ok, user, token}
|
||||
end
|
||||
|
||||
defp token_options(type) do
|
||||
case type do
|
||||
:access -> [token_type: "access", ttl: {2, :hour}]
|
||||
:reset -> [token_type: "reset", ttl: {15, :minute}]
|
||||
:admin -> [token_type: "admin", ttl: {90, :day}]
|
||||
end
|
||||
end
|
||||
|
||||
def after_encode_and_sign(resource, claims, token, _options) do
|
||||
with {:ok, _} <- Guardian.DB.after_encode_and_sign(resource, claims["typ"], claims, token) do
|
||||
{:ok, token}
|
||||
end
|
||||
end
|
||||
|
||||
def on_verify(claims, token, _options) do
|
||||
with {:ok, _} <- Guardian.DB.on_verify(claims, token) do
|
||||
{:ok, claims}
|
||||
end
|
||||
end
|
||||
|
||||
def on_revoke(claims, token, _options) do
|
||||
with {:ok, _} <- Guardian.DB.on_revoke(claims, token) do
|
||||
{:ok, claims}
|
||||
end
|
||||
end
|
||||
|
||||
def on_refresh({old_token, old_claims}, {new_token, new_claims}, _options) do
|
||||
with {:ok, _, _} <- Guardian.DB.on_refresh({old_token, old_claims}, {new_token, new_claims}) do
|
||||
{:ok, {old_token, old_claims}, {new_token, new_claims}}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
defmodule PhoenixApiTemplateWeb.UserController do
|
||||
use PhoenixApiTemplateWeb, :controller
|
||||
|
||||
alias PhoenixApiTemplateWeb.Auth.ErrorResponse
|
||||
alias PhoenixApiTemplateWeb.Auth.ErrorResponse.Unauthorized
|
||||
alias PhoenixApiTemplateWeb.Auth.ErrorResponse.Forbidden
|
||||
alias PhoenixApiTemplateWeb.Auth.ErrorResponse.NotFound
|
||||
alias PhoenixApiTemplateWeb.Auth.Guardian
|
||||
alias PhoenixApiTemplate.Accounts
|
||||
alias PhoenixApiTemplate.Accounts.User
|
||||
@@ -20,7 +21,7 @@ defmodule PhoenixApiTemplateWeb.UserController do
|
||||
if conn.assigns.user.id == user.id do
|
||||
conn
|
||||
else
|
||||
raise ErrorResponse.Forbidden
|
||||
raise Forbidden
|
||||
end
|
||||
end
|
||||
|
||||
@@ -40,7 +41,11 @@ defmodule PhoenixApiTemplateWeb.UserController do
|
||||
end
|
||||
|
||||
def sign_in(conn, %{"email" => email, "password" => password}) do
|
||||
case Guardian.authenticate(email, password) do
|
||||
authorize_account(conn, email, password)
|
||||
end
|
||||
|
||||
defp authorize_account(conn, email, hash_password) do
|
||||
case Guardian.authenticate(email, hash_password) do
|
||||
{:ok, user, token} ->
|
||||
conn
|
||||
|> Plug.Conn.put_session(:user_id, user.id)
|
||||
@@ -52,6 +57,17 @@ defmodule PhoenixApiTemplateWeb.UserController do
|
||||
end
|
||||
end
|
||||
|
||||
def sign_out(conn, %{}) do
|
||||
user = conn.assigns[:user]
|
||||
token = Guardian.Plug.current_token(conn)
|
||||
Guardian.revoke(token)
|
||||
|
||||
conn
|
||||
|> Plug.Conn.clear_session()
|
||||
|> put_status(:ok)
|
||||
|> render("user_token.json", %{user: user, token: nil})
|
||||
end
|
||||
|
||||
def show(conn, %{"id" => id}) do
|
||||
user = Accounts.get_user!(id)
|
||||
render(conn, "show.json", user: user)
|
||||
@@ -72,4 +88,27 @@ defmodule PhoenixApiTemplateWeb.UserController do
|
||||
send_resp(conn, :no_content, "")
|
||||
end
|
||||
end
|
||||
|
||||
def refresh_session(conn, %{}) do
|
||||
old_token = Guardian.Plug.current_token(conn)
|
||||
|
||||
case Guardian.decode_and_verify(old_token) do
|
||||
{:ok, claims} ->
|
||||
case Guardian.resource_from_claims(claims) do
|
||||
{:ok, user} ->
|
||||
{:ok, _old, {new_token, _new_claims}} = Guardian.refresh(old_token)
|
||||
|
||||
conn
|
||||
|> Plug.Conn.put_session(:user_id, user.id)
|
||||
|> put_status(:ok)
|
||||
|> render("user_token.json", %{user: user, token: new_token})
|
||||
|
||||
{:error, _reason} ->
|
||||
raise NotFound
|
||||
end
|
||||
|
||||
{:error, _reason} ->
|
||||
raise NotFound
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -45,5 +45,7 @@ defmodule PhoenixApiTemplateWeb.Router do
|
||||
|
||||
get "/users/by_id/:id", UserController, :show
|
||||
put "/users/:id", UserController, :update
|
||||
get "/user/refresh_session", UserController, :refresh_session
|
||||
get "/sign_out", UserController, :sign_out
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,7 +11,8 @@ defmodule PhoenixApiTemplateWeb.Telemetry do
|
||||
children = [
|
||||
# Telemetry poller will execute the given period measurements
|
||||
# every 10_000ms. Learn more here: https://hexdocs.pm/telemetry_metrics
|
||||
{:telemetry_poller, measurements: periodic_measurements(), period: 10_000}
|
||||
{:telemetry_poller, measurements: periodic_measurements(), period: 10_000},
|
||||
{Guardian.DB.Token.SweeperServer, []}
|
||||
# Add reporters as children of your supervision tree.
|
||||
# {Telemetry.Metrics.ConsoleReporter, metrics: metrics()}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user