Auth implementation for the Supabase Potion SDK in Elixir.
def deps do
[
{:supabase_potion, "~> 0.5"},
{:supabase_gotrue, "~> 0.3"}
]
end
Firstly you need to initialize your Supabase client(s) as can be found on the Supabase Potion documentation.
Now you can pass the Client to the Supabase.GoTrue
functions:
iex> Supabase.GoTrue.sign_in_with_password(client, %{} = params)
Note that this example consider that you already have a
client
variable with the Supabase client.
Note that this example consider that you al already configured the
Supabase.GoTrue
module in your configuration file. As mentioned in the next section.
This implementation also exposes an Supabase.GoTrue.Admin
function to interact with users with super powers:
iex> Supabase.GoTrue.Admin.create_user(client, %{} = params)
There are sample apps in the examples
directory that demonstrate how to use the Supabase.GoTrue
module in your application.
Check the Supabase Potion examples showcase!
You can configure the Supabase.GoTrue
module in your config.exs
file:
import Config
config :supabase_gotrue, auth_module: MyAppWeb.Auth
- Sign in with ID Token
- Sign in with email and password
- Sign in with Oauth
- Sign in with OTP
- Sign in with SSO
- Anonymous Sign in
- Sign up with email and password
Supabase.GoTrue.Plug
provides Plug-based authentication support for the Supabase GoTrue
authentication in Elixir applications.
The module offers a series of functions to manage user authentication through HTTP requests in Phoenix applications with "dead views" or plain Plug based application. It facilitates operations like signing-in, signing-out, fetch the current user, and more.
To use the Supabase.GoTrue.Plug
module, you need first to define a module that will handle the authentication in your application:
defmodule MyAppWeb.Auth do
use Supabase.GoTrue.Plug,
client: MyApp.Supabase.Client,
endpoint: MyAppWeb.Endpoint, # required if using Phoenix based applications
signed_in_path: "/app", # required
not_authenticated_path: "/login", # required
session_cookie: "my_app_session", # optional
# optional
session_cookie_options: [
http_only: true,
secure: true,
same_site: :lax,
max_age: 86_400
]
end
Warning
The client
options must be a module that implements the Supabase.Client.Behaviour
behaviour.
It should be a Self Managed Client but it can be a One off Client if you correctly manage the client state on your application.
So, considering that you have something like this on your config.exs
:
config :my_app, MyApp.Supabase.Client,
base_url: "https://myapp.supabase.co",
api_key: "myapp-api-key"
And you have already defined your self managed client module:
# lib/my_app/supabase/client.ex
defmodule MyApp.Supabase.Client do
use Supabase.Client, otp_app: :my_app
end
Then you can use the Supabase.GoTrue.Plug
module! The module define a series of plugs that you can use in your router:
import MyAppWeb.Auth
plug :fetch_current_user # this plug will fetch the current user and assign it to the `conn.assigns[:current_user]`
plug :redirect_if_user_is_authenticated # this plug will redirect to the `signed_in_path` if the user is authenticated
plug :require_authenticated_user # this plug will redirect to the `not_authenticated_path` if the user is not authenticated
For example, in your Phoenix router you can use your defined authentication handler module like this:
defmodule MyAppWeb.Router do
use MyAppWeb, :router
import MyAppWeb.Auth
pipeline :browser do
# rest of plugs
plug :fetch_current_user
end
# if a user is already authenticted, redirect to the signed_in_path
# already authenticated users will not be able to access this scope
scope "/", MyAppWeb do
pipe_through [:browser, :redirect_if_user_is_authenticated]
get "/login", LoginController, :show
post "/login", LoginController, :create
end
# if a user is not authenticated, redirect to the not_authenticated_path
# not authenticated users will not be able to access this scope
scope "/app", MyAppWeb do
pipe_through [:browser, :require_authenticated_user]
get "/", AppController, :index
end
end
Also, Supabase.GoTrue.Plug
provides a series of helper functions that you can use in your login/auth controllers, so with your defined module you can use like this:
defmodule MyApp.LoginController do
use MyAppWeb, :controller
import MyAppWeb.Auth
def show(conn, _params) do
render(conn, "login.html")
end
def create(conn, %{"email" => email, "password" => password}) do
case log_in_with_password(conn, %{"email" => email, "password" => password}) do
{:ok, updated_conn} ->
# here the `updated_conn` will contain the access token
# and also will redirect to the `signed_in_path`
put_flash(updated_conn, :info, "You have successfully signed in!")
# this clause means that the user provided invalid credentials
# so we will render the login form again with an error message
{:error, _reason} ->
conn
|> put_flash(:error, "Invalid email or password")
|> render("login.html")
end
end
end
The log_in_with_password/2
exposed by the Supabase.GoTrue.Plug
module is one of the various ways that you can start a session with the Supabase GoTrue
authentication service.
For more ways to authenticate users, please refer to the Supabase.GoTrue module documentation and the official Supabase documentation.
If you're new to the Plug
library, you can learn more about it in the official documentation.
Also if you're new to the Phoenix framework, you can learn more about it in the official getting started section.
Similar to the Supabase.GoTrue.Plug
module, the Supabase.GoTrue.LiveView
module provides LiveView-based authentication support for the Supabase GoTrue
authentication in Elixir applications.
Supabase.GoTrue.LiveView
defines Server Hooks that you can use in your LiveView modules to manage user authentication through WebSocket connections in Phoenix LiveView applications. These hooks are meant to be used as on-mount callbacks in your LiveView modules or live_session/3 definitions on your router.
To use the Supabase.GoTrue.LiveView
module, you need first to define a module that will handle the authentication in your application:
defmodule MyAppWeb.Auth do
use Supabase.GoTrue.LiveView,
client: MyApp.Supabase.Client, # required
endpoint: MyAppWeb.Endpoint, # required
signed_in_path: "/app", # required
not_authenticated_path: "/login" # required
end
Warning
The client
options must be a module that implements the Supabase.Client.Behaviour
behaviour.
It should be a Self Managed Client but it can be a One off Client if you correctly manage the client state on your application.
So, considering that you have something like this on your config.exs
:
config :my_app, MyApp.Supabase.Client,
base_url: "https://myapp.supabase.co",
api_key: "myapp-api-key"
And you have already defined your self managed client module:
# lib/my_app/supabase/client.ex
defmodule MyApp.Supabase.Client do
use Supabase.Client, otp_app: :my_app
end
Then in your LiveView module, you can use the module that you defined like this:
defmodule MyAppWeb.UserLive do
use MyAppWeb, :live_view
on_mount {MyAppWeb.Auth, :mount_current_user}
on_mount {MyAppWeb.Auth, :ensure_authenticated}
def mount(_params, _session, socket) do
# here you will have the `socket.assigns[:current_user]` available
# and if the user is not authenticated, the user will be redirected to the `not_authenticated_path`
{:ok, socket}
end
end
The usage with the live_session/3
definition is similar. In your router:
defmodule MyAppWeb.Router do
use MyAppWeb, :router
scope "/app", MyAppWeb do
live_session :authenticated,
on_mount: [
{MyAppWeb.Auth, :mount_current_user},
{MyAppWeb.Auth, :ensure_authenticated}
] do
live "/user", UserLive
end
end
end
If you're new to Phoenix LiveView, you can learn more about it in the official documentation.