Current section
Files
Jump to
Current section
Files
lib/auth.ex
defmodule SsoLogin.Auth do
@moduledoc """
SSO登录校验
"""
require Logger
import Plug.Conn
import SsoLogin.Util
alias SsoLogin.User
@sso_api_url "https://sso.helijia.com/sso/user/httpUser"
@login_url "https://sso.helijia.com/sso/login"
def init(options) do
options
end
def call(conn, options) do
user = get_user_from_session(conn) || get_user_from_sso(conn, options)
if should_process?(conn, options) do
set_resp(conn, user)
else
conn
end
end
def sso_api_url do
Application.get_env(:sso_login, :sso_api_url) || @sso_api_url
end
def login_api_url do
Application.get_env(:sso_login, :login_api_url) || @login_url
end
## Private
defp set_resp(conn, user = %{}) do
conn |> fetch_session |> put_session(:sso_current_user, user)
end
defp set_resp(conn, nil) do
login_url = get_login_url(conn)
conn
|> put_resp_header("location", login_url)
|> send_resp(302, "Redirect!")
|> halt
end
defp get_user_from_session(conn) do
conn |> fetch_session |> get_session(:sso_current_user)
end
defp get_user_from_sso(conn, options) do
conn |> get_token |> request_user |> post_login(options)
end
defp get_token(conn) do
conn = fetch_cookies(conn)
conn.cookies["sso_token"]
end
defp request_user(token) when is_binary(token) do
url = "#{sso_api_url()}?token=#{token}"
Logger.debug("try get sso user, GET " <> url)
%{body: body} = HTTPoison.get!(url)
Logger.debug(body)
Jason.decode!(body)
end
defp request_user(_) do
nil
end
defp post_login(%{"success" => true, "data" => user}, options) do
hook = options[:post_login]
user = User.from_data(user)
if hook do
{module, method} = hook
apply(module, method, [user])
else
user
end
end
defp post_login(_ret, _opts) do
nil
end
defp get_login_url(conn) do
url = get_request_url(conn)
qs = URI.encode_query(%{"doneUrl" => url})
"#{login_api_url()}?#{qs}"
end
defp should_process?(%{request_path: path}, options) do
case options[:ignore] do
nil -> true
list -> not Enum.any?(list, &(path =~ &1))
end
end
end