Haytni.LiveViewPlugin (Haytni v0.7.0) View Source

This module "replace" the _csrf_token generated by Phoenix, if you can't use it (mainly because of caching), to recognize the current authenticated user in channels and, by extension, live view since access to session through websocket rely on this _csrf_token. To do so, this module provides a controller to deliver short lived ciphered and signed token which you request in Javascript (ajax is the main way) and send it back to the server for the websocket connection. Then, Haytni will set the current user for the websocket when you call connect/4 from your Phoenix.Socket.connect/3 callback (channels) and mount_user/4 from your c:Phoenix.LiveView.mount/3 (live view).

Configuration:

  • remote_ip_header (default: nil): if a proxy in front of phoenix follows you the IP address of the client through a specific header, explicit it here. For example, with nginx configured with proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;, set remote_ip_header: "x-forwarded-for"

  • token_validity (default: {2, :minute}): duration of generated token. You should keep it as short as possible (not more than few minutes) since these tokens are intended to be used right after they were requested

  • socket_id (default: nil): a function to resolve a user into a socket's name. This function, from a module (your Haytni's stack) and a user, should return a string (binary) that identify a socket, the same value returned by your Phoenix.Socket.id/1 callback

    stack Haytni.LiveViewPlugin,
      socket_id: nil,
      token_validity: {2, :minute}
      remote_ip_header: nil,

Routes: haytni_<scope>_token_path (action: create): default path is "/token" but you can override it by the :token_path option when calling YourApp.Haytni.routes/1 from your router

Link to this section Summary

Functions

For channels, to be called in Phoenix.Socket.connect/3 callback in order to set the current user in assigns (named :current_user by default - same way as it is done for Plug.Conn).

Extract metadata and real token from a previously "encoded" token by encode_token/3

Add metadata (IP address) to token then hash and cipher the whole.

Callback implementation for Haytni.Plugin.fields/1.

For live view, to be called in c:Phoenix.LiveView.mount/3 callback in order to set the current user in assigns (named :current_user by default - same way as it is done for Plug.Conn).

Link to this section Functions

Link to this function

connect(module, params, socket, connect_info)

View Source

Specs

connect(
  module :: module(),
  params :: map(),
  socket :: Phoenix.Socket.t(),
  connect_info :: map()
) :: {:ok, Phoenix.Socket.t()}

For channels, to be called in Phoenix.Socket.connect/3 callback in order to set the current user in assigns (named :current_user by default - same way as it is done for Plug.Conn).

Example rejecting anonymous connections:

# lib/your_app_web/channels/user_socket.ex
defmodule YourAppWeb.UserSocket do
  @impl Phoenix.Socket
  def connect(params, socket, connect_info) do
    result = {:ok, socket} = Haytni.LiveViewPlugin.connect(YourApp.Haytni, params, connect_info)
    if socket.assigns.current_user do
      result
    else
      :error
    end
  end
end
Link to this function

connect(module, config, params, socket, connect_info)

View Source

Specs

connect(
  module :: module(),
  config :: Haytni.LiveViewPlugin.Config.t(),
  params :: map(),
  socket :: Phoenix.Socket.t(),
  connect_info :: map()
) :: {:ok, Phoenix.Socket.t()}
Link to this function

decode_token(config, token_param)

View Source

Specs

decode_token(
  config :: Haytni.LiveViewPlugin.Config.t(),
  token_param :: String.t()
) :: {:ok, %{required(String.t()) => String.t()}} | :error

Extract metadata and real token from a previously "encoded" token by encode_token/3

Link to this function

encode_token(conn, token, config)

View Source

Specs

encode_token(
  conn :: Plug.Conn.t(),
  token :: Haytni.Token.t(),
  config :: Haytni.LiveViewPlugin.Config.t()
) :: String.t()

Add metadata (IP address) to token then hash and cipher the whole.

Callback implementation for Haytni.Plugin.fields/1.

Link to this function

files_to_install(base_path, web_path, scope, timestamp)

View Source

Callback implementation for Haytni.Plugin.files_to_install/4.

Link to this function

find_user(conn, module, config)

View Source

Callback implementation for Haytni.Plugin.find_user/3.

Link to this function

invalid?(user, module, config)

View Source

Callback implementation for Haytni.Plugin.invalid?/3.

Link to this function

mount(module, params, session, socket)

View Source

Specs

mount(
  module :: module(),
  params :: map(),
  session :: map(),
  socket :: Phoenix.LiveView.Socket.t()
) :: Phoenix.LiveView.Socket.t() | no_return()

For live view, to be called in c:Phoenix.LiveView.mount/3 callback in order to set the current user in assigns (named :current_user by default - same way as it is done for Plug.Conn).

Example:

# lib/your_app_web/live/your_view_live.ex
defmodule YourAppWeb.YourViewLive do
  @impl Phoenix.LiveView
  def mount(params, session, socket) do
    socket = Haytni.LiveViewPlugin.mount(YourApp.Haytni, params, session, socket)

    {:ok, socket}
  end
end
Link to this function

on_delete_user(multi, user, module, config)

View Source

Callback implementation for Haytni.Plugin.on_delete_user/4.

Link to this function

on_email_change(multi, changeset, module, config)

View Source

Callback implementation for Haytni.Plugin.on_email_change/4.

Link to this function

on_failed_authentication(user, multi, keywords, module, config)

View Source

Callback implementation for Haytni.Plugin.on_failed_authentication/5.

Link to this function

on_registration(multi, module, config)

View Source

Callback implementation for Haytni.Plugin.on_registration/3.

Link to this function

on_successful_authentication(conn, user, multi, keywords, module, config)

View Source

Callback implementation for Haytni.Plugin.on_successful_authentication/6.

Link to this function

validate_create_registration(changeset, module, config)

View Source

Callback implementation for Haytni.Plugin.validate_create_registration/3.

Link to this function

validate_password(changeset, module, config)

View Source

Callback implementation for Haytni.Plugin.validate_password/3.

Link to this function

validate_update_registration(changeset, module, config)

View Source

Callback implementation for Haytni.Plugin.validate_update_registration/3.