Vue,js 与 Supabase 一起使用 - 使用 Oauth 登录后无法更新登录按钮

Vue,js used with Supabase - can't update signIn button after logging in with Oauth

async handleSignInSignOutButtonClick() {
  if (!this.isSignedIn) {
    supabase.auth.signIn({ provider: "google" });
    this.$store.commit("signIn", supabase.auth.session());
    window.location.reload();
    return;
  }

  await this.$store.commit("signOut");
  supabase.auth.signOut();
  window.location.reload();
},

以上功能是由登录按钮触发的,登录按钮应该是退出按钮和用户登录后的图标。

当函数触发时,supabase 将我重定向到 Google OAuth 同意屏幕。但是,在登录并重定向回我的应用程序后,登录按钮一直保留在那里,直到我手动刷新页面。

我的代码有什么问题...

您需要注意一些正在发生的事情。对于初学者,当您不需要在 handleSignInSignOutButtonClick() 函数中重新加载页面时。

当身份验证过程开始时,您的应用程序将被重定向到您发现的 Google OAuth 同意屏幕。身份验证完成后,您将被重定向回您的应用程序并自动重新加载。

第二点是可以利用supabase.auth.onAuthStateChange()活动来帮助你。我的建议是在您创建 supabase 客户端时监听此事件,以便它监听您的应用程序实例的持续时间。在该事件处理期间,您可以根据状态更改将用户分配到商店(或您想要保存用户数据的任何地方)。您的应用可以对状态变化作出反应。

在您的 supabase 客户端设置代码中:

const supabaseUrl = process.env.SUPABASE_URL // your supabaseUrl
const supabaseAnonKey = process.env.SUPABASE_ANON_KEY // your supabaseKey

const supabase = createClient(supabaseUrl, supabaseAnonKey)

/**
* Set up the authentication state change listener
* 
* @param  {string} event The event indicates what state changed (SIGN_IN, SIGN_OUT etc)
* @param  {object} session The session contains the current user session data or null if there is no user
*/
supabase.auth.onAuthStateChange((event, session) => {
      
  const user = session?.user || null;

  // Save your user to your desired location
  $store.commit("user", user);
});

现在,只要用户登录,您的用户数据就会被保存,而当用户注销时,用户数据就会被设置为空。此外,任何页面刷新都由更改状态事件侦听器或任何其他可能更改用户状态的实例处理。例如,您可以有其他登录或注销按钮,单个侦听器会选择它们。

接下来就是处理登录或注销的实际过程。在您的组件 Vue 文件中(来自您的示例):

async handleSignInSignOutButtonClick() {
      
  if ($store.state.user === null) {
    await supabase.auth.signIn(
      { provider: "google" },
      { redirectTo: "where_to_go_on_login" }))
  } else {
    await supabase.auth.signOut()
    $router.push("your_logged_out_page")
  }
}

最后,对于您的按钮更改状态以指示已登录或已注销,您可以简单地观察商店用户状态。

<button v-if="user">Sign Out</button>
<button v-else>Sign In</button>

这样,只要用户状态发生变化,您的按钮就会更新。每当用户登录或注销时,用户状态都会发生变化,并且您的代码更加紧凑和可读。

最后一次观察您可能已经在做。我建议您将所有身份验证代码放入一个文件中,并公开登录和注销功能供您的应用程序用作组件文件中使用的导出。这样,与登录和注销有关的所有事情都在一个位置处理,并且此代码从组件文件中抽象出来。如果你想从 Supabase 切换,你可以轻松更新一个或两个文件,其他一切都会继续工作。