我正在开发 Phoenix 1.6 应用程序。我通过 GitHub 使用 Ueberauth 进行身份验证,它正在工作。我设置了一个发布主题和评论的频道,经过身份验证的用户可以这样做。接下来,我尝试添加一个用户令牌以在频道中使用。我按照使用mix phx.new.socket User创建的样板代码中的说明进行操作。在user_socket.js文件中,有在模板中创建令牌的说明,它有效。令牌在连接函数的user_socket.ex中进行验证。我在router.ex中创建了一个新插件put_user_token以将令牌添加到conn,这也有效。但是,我对插件中的逻辑有疑问。这是我的代码:
defp put_user_token(conn, _) do
if conn.assigns.user do
token = Phoenix.Token.sign(conn, "user socket", conn.assigns.user.id)
assign(conn, :user_token, token)
else
conn
end
只要我登录就可以使用。问题是当我注销并尝试重新登录时。插件中 if 语句的样板代码是:
if current_user = conn.assigns[:current_user] do
我的代码不同,因为当前用户被定义为user,其值等于数据库中用户记录的 id。我认为问题在于,在设置 Ueberauth 时,我创建了另一个插件SetUser,它位于put_user_token插件之前。这是 SetUser 的调用函数:
def call(conn, _opts) do
user_id = get_session(conn, :user_id)
cond do
user = user_id && Repo.get(User, user_id) ->
assign(conn, :user, user)
true ->
assign(conn, :user, nil)
end
end
似乎正在发生的事情是,在我注销后,应用程序重定向到主页,这导致插件执行,并且conn.assigns.user的值设置为nil。然后发生错误,我无法重新登录。
我需要想出一种方法让put_user_token插件中的if语句能够处理nil值。我尝试了 is_integer(conn.assigns.user)和其他一些比较,但如果存在nil值,则应用程序崩溃。