1

我们使用 Guardian 生成令牌,然后在连接到 Phoenix Channels 的套接字时将其用于身份验证。

最近我们发现有些用户从不离开某些页面,并且在一个月左右之后,令牌变得无效,这使得凤凰频道的连接尝试无效。

您如何在客户端处理此类情况?有没有特定的错误可以从 Phoenix 返回让前端知道是什么原因?我们的connect函数user_socket.ex如下所示:

def connect(%{"guardian_token" => token}, socket) do
  case Guardian.Phoenix.Socket.authenticate(socket, MyApp.Guardian, token) do
    {:ok, authed_socket} ->
      {:ok, authed_socket}

    {:error, _} ->
      :error
  end
end

有没有办法使用 Phoenix 频道的 Phoenix JS 库捕获此错误?我们的目标是 1)在令牌过期时阻止它重试,2)可能注销用户或显示用户离线的消息。我们检查了Phoenix JS 的文档,但找不到任何合适的。

4

2 回答 2

0

这可以在客户端处理。

这是一些演示自动断开流程的伪代码:

// Assuming you are adding the token (JWT) to the socket URL's query parameters
const socket = new Socket(url, { params: { jwt }});
socket.connect();

// Listen to socket errors
socket.onError(error => {
  if (!isValidJwt(jwt)) {
    console.log("JWT is no longer valid. Disconnecting.");
    socket.disconnect();
  }
})

function isValidJwt(jwt) {
  // Provide your own validation logic here
  // For JWTs, you can parse the JWT, read the expiration time,
  // and compare it with the current time.
}

此外,您可以通过对服务器端代码进行临时修改来进行本地测试。

在生成身份验证令牌的地方,给令牌一个小的生存时间 (TTL):

// Temporary change, for testing
conn = MyApp.Guardian.Plug.sign_in(conn, user, %{}, ttl: {10, :second})

这会使 JWT 在 10 秒后过期。

通过修改后的服务器端更改,让客户端登录并连接到套接字。杀死 Phoenix 服务器以触发socket对象的自动重新连接机制。当socket错误尝试重新连接时,您的回调函数会注意到令牌不再有效,并且它将断开套接字。

于 2021-10-05T21:24:19.920 回答
0

您可以尝试在每次连接时或在您认为合适的时候刷新令牌

也许是这样的

# Refresh a token and set it on connect
def connect(%{"guardian_token" => token}, socket) do

  case MyApp.Guardian.refresh(token) do

    {:ok, _old_stuff, {new_token, new_claims}} -> 
      case Guardian.Phoenix.Socket.authenticate(socket, MyApp.Guardian, new_token, new_claims) do
        {:ok, authed_socket} ->
          {:ok, authed_socket}
        {:error, _} ->
          :socket_auth_failed
      end

    _ ->
      {:token_refresh_failed, "could not refresh token"}
  end
end

于 2019-02-14T07:31:46.000 回答