使用Session认证Phoenix Socket

Author:Gao
Created At:2022-04-14

使用Session认证Phoenix Socket

Purpose

由于在http页面中创建websocket连接, 需要每次都在页面上分配token, 之后还需要重新建立连接, 开发很麻烦, 所以考虑直接使用http中的session来进行认证

Inplement

  1. 启用socket中的session信息
# file endpoint.ex
  socket "/socket", GSMLGWeb.UserSocket,
    websocket: [
      connect_info: [
        :peer_data,
        :trace_context_headers,
        :x_headers,
        :uri,
        {:session, @session_options}
      ]
    ]
  1. 配置客户端连接时必须添加csrf_token
const csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content");
const params = { _csrf_token: csrfToken };
if (token != null) {
  params.token = token;
}
const socket = new Socket("/socket", { params });
  1. 在认证中匹配
# user_socket.ex
  @impl true
  def connect(%{"_csrf_token" => _csrf_token}, socket, connect_info) do
    %{session: %{"guardian_default_token" => token}} = connect_info
    claims_to_check = %{}
    key = Guardian.Plug.default_key()

    with {:ok, resource, claims} <-
           Guardian.resource_from_token(GSMLGWeb.Guardian, token, claims_to_check, []) do
      authed_socket = Guardian.Phoenix.Socket.assign_rtc(socket, resource, token, claims, key)

      {:ok, authed_socket}
    else
      _ -> :error
    end
  end