Vue3中如何使用Supabase Auth方法

广告:宝塔Linux面板高效运维的服务器管理软件 点击【 https://www.bt.cn/p/uNLv1L 】立即购买

Vue3中如何使用Supabase Auth方法

引言

Supabase自称是一款“替代开源Firebase”的工具。我对与Supbase合作已经有一段时间了,我想我将尝试使用他们的认证API来为Vue.js 3应用程序进行认证设置。

首先,你为什么要使用Supabase Auth?最重要的是,如果你使用Supabase作为你的数据存储,(它有一些非常甜蜜的好处),Supabase Auth是你可以管理对这些数据的访问的唯一方法。其次,虽然Supabase Auth也有许多不同的功能。

没有中间件的用户权限(通过Postgres的行级安全)。

神奇的电子邮件链接

社交提供者的登录

以及所有其他你期望的封装在一个简单的JavaScript SDK中的Auth功能

综上所述,值得一提的是,Supabase Auth不是一个独立的认证提供商,它只是为了与其他Supabase服务(数据、存储等)一起使用。

好了,让我们开始在我们的Vue.js 3应用程序中实施Supabase Auth。

安装Supabase

我假设你已经有了一个用Vue Router设置的Vue.js 3应用程序,如果没有,你可以下载这个模板代码来进行操作。我还假设你已经有了一个Supabase账户和项目设置。如果你还没有,可以访问supabase.io,该网站会引导你完成第一步。

然后,为了与Supabase auth以及它的任何其他服务合作,我们需要安装Supabase JavaScript SDK。

npm install @supabase/supabase-js
登录后复制设置Supabase

安装完Supabase后,我们需要经过几个步骤来设置它。我将创建一个名为UseSupabase.js 的组合,用来组织这个设置。

// UseSupabase.jsimport { createClient } from "@supabase/supabase-js";// these can come from an environment variable if desired// not required however as they are 100% exposed on the client side anyway // and that's ok, Supabase expects this (security is provided by Row Level Security)const supabaseUrl = "";const supabaseKey = "";// setup clientconst supabase = createClient(supabaseUrl, supabaseKey);// expose supabase clientexport default function useSupabase() {  return { supabase };}
登录后复制

supabaseUrl和supabaseKey可以在Supabase仪表板上的Settings > API

当你在Supabase界面时,你也可以到Autentication > Settings ,设置你的网站网址,以便Supabase知道如何正确地重定向确认邮件等。它的默认值是localhost:3000,但你可以根据需要进行修改。

创建一个AuthUser组合

设置好Supabase SDK后,我们现在可以开始使用它了。首先,我将创建一个AuthUser组合,以抽象出与AuthUser的一些交互,并存留所有我们需要填写的方法。这将在我们希望离开Supabase时大有裨益,同时也有助于将所有的AuthUser功能整合到一个地方。

import { ref } from "vue";// user is set outside of the useAuthUser function// so that it will act as global state and always refer to a single userconst user = ref(null);export default function useAuthUser() {  /**   * Login with email and password   */  const login = async ({ email, password }) => {};  /**   * Login with google, github, etc   */  const loginWithSocialProvider = (provider) => {};  /**   * Logout   */  const logout = async () => {};  /**   * Check if the user is logged in or not   */  const isLoggedIn = () => {};  /**   * Register   */  const register = async ({ email, password, ...meta }) => {};  /**   * Update user email, password, or meta data   */  const update = async (data) => {};  /**   * Send user an email to reset their password   * (ie. support "Forgot Password?")   */  const sendPasswordRestEmail = async (email) => {};  return {    user,    login,    loginWithSocialProvider,    isLoggedIn,    logout,    register,    update,    sendPasswordRestEmail,    maybeHandleEmailConfirmation,  };}
登录后复制创建页面

接下来,让我们来创建典型用户认证流程所需的页面。我使用了Tailwind CSS进行样式设计,不过这些样式可以根据你的需求进行自由调整。

注册.vue

我们需要的第一个页面是一个注册页面。它需要包含必要的字段,以便在Supabase中创建一个用户。这些字段是电子邮件和密码。我们也可以在Supabase中为我们的用户添加任意的元数据,这意味着我们也可以让用户的真实姓名成为注册的一部分。

// Register.vue<script>...</script><template>  <form class="max-w-lg m-auto" @submit.prevent="handleSubmit">    <h2 class="text-3xl mb-5">Register</h2>    <label>Name <input v-model="form.name" type="text" /></label>    <label>Email <input v-model="form.email" type="email" /></label>    <label>Password <input v-model="form.password" type="password" /></label>    <button>Register</button>  </form></template>
登录后复制

我们可以使用一个响应式引用来追踪表单数据,并提供一个函数来处理表单的提交,这个函数也可以放在脚本部分中。在表单提交时,我们将从AuthUser组合中调用注册函数(它仍然是空的,但我们将在稍后用supabase的具体调用来填充它),然后重定向到一个页面,指示用户检查他们的电子邮件以确认注册。

// Register.vue<script setup>import { ref } from "vue";import useAuthUser from "@/composables/UseAuthUser";import { useRouter } from "vue-router";// Use necessary composablesconst router = useRouter();const { register } = useAuthUser();// Form reactive ref to keep up with the form dataconst form = ref({  name: "",  email: "",  password: "",});// function to hand the form submitconst handleSubmit = async () => {  try {        // use the register method from the AuthUser composable    await register(form.value);        // and redirect to a EmailConfirmation page the will instruct        // the user to confirm they're email address    router.push({      name: "EmailConfirmation",      query: { email: form.value.email },    });  } catch (error) {    alert(error.message);  }};</script><template>...</template>
登录后复制

最后,我们需要为该页面注册路由。

// router/index.jsconst routes = [  //...    {    name: "Register",    path: "/register",    component: () => import("@/pages/Register.vue"),  },]
登录后复制

如果你使用了模板代码,访问/register ,应该会得到一个看起来像这样的页面。

EmailConfirmation.vue

既然我们要重定向到一个EmailConfirmation页面,那么需要确保它存在。它将只是一个简单的模板和一条信息。我们已经将来自注册表单的电子邮件作为一个查询变量提供,因此在这里可以显示它,同时进行重定向。

<template>  <div>    <h2 class="text-3xl">Thanks for registering!</h2>    <p>      Please confirm your email to finishing registering:      {{ $route.query.email }}    </p>  </div></template>
登录后复制

再一次,我们也需要注册这个路由。

// router/index.jsconst routes = [    //...    {    name: "EmailConfirmation",    path: "/email-confirmation",    component: () => import("@/pages/EmailConfirmation.vue"),    },]
登录后复制

现在访问带有电子邮件查询变量的/email-confirmation 路由将看起来像这样。

/[email protected]

登录.vu

在注册并确认了他们的电子邮件后,用户将不得不登录。让我们接下来创建这个页面。

该模板将包括一个带有电子邮件和密码字段的表单,以及一个指向忘记密码页面的链接,还有一个处理Github登录的链接。

<script>...</script><template>  <div class="max-w-lg m-auto">    <form @submit.prevent="handleLogin">      <h2 class="text-3xl mb-5">Login</h2>      <label>Email <input v-model="form.email" type="email" /></label>      <label>Password <input v-model="form.password" type="password" /></label>      <button>Login</button>      <router-link to="/forgotPassword">Forgot Password?</router-link>    </form>    <div class="mt-5">      <a @click.prevent="handleLogin('github')">Github</a>    </div>  </div></template>
登录后复制

在脚本部分,我们可以创建一个反应式引用来跟上表单的值,以及一个函数来处理表单的提交。

<script setup>import { ref } from "vue";import useAuthUser from "@/composables/UseAuthUser";import { useRouter } from "vue-router";// Use necessary composablesconst router = useRouter();const { login, loginWithSocialProvider } = useAuthUser();// keep up with form dataconst form = ref({  email: "",  password: "",});// call the proper login method from the AuthUser composable// on the submit of the formconst handleLogin = async (provider) => {  try {    provider      ? await loginWithSocialProvider(provider)      : await login(form.value);    router.push({ name: "Me" });  } catch (error) {    alert(error.message);  }};</script><template>...</template>
登录后复制

注册完路由后,你可以访问/login 路由,看到一个漂亮的登录表单。

// UseSupabase.jsimport { createClient } from "@supabase/supabase-js";// these can come from an environment variable if desired// not required however as they are 100% exposed on the client side anyway // and that's ok, Supabase expects this (security is provided by Row Level Security)const supabaseUrl = "";const supabaseKey = "";// setup clientconst supabase = createClient(supabaseUrl, supabaseKey);// expose supabase clientexport default function useSupabase() {  return { supabase };}0
登录后复制ForgotPassword.vue

由于我们在上面实现了一个忘记密码的链接,让我们也把这个页面用脚手架搭出来。

在模板中,我们只需要一个带有单个电子邮件字段的表单,以便收集我们应该发送重置链接的电子邮件。

// UseSupabase.jsimport { createClient } from "@supabase/supabase-js";// these can come from an environment variable if desired// not required however as they are 100% exposed on the client side anyway // and that's ok, Supabase expects this (security is provided by Row Level Security)const supabaseUrl = "";const supabaseKey = "";// setup clientconst supabase = createClient(supabaseUrl, supabaseKey);// expose supabase clientexport default function useSupabase() {  return { supabase };}1
登录后复制

在脚本部分,我们将创建一个电子邮件反应式参考,以跟上表单中的电子邮件输入,并定义一个函数,在表单提交时调用AuthUser可组合的sendPasswordRestEmail 函数。

// UseSupabase.jsimport { createClient } from "@supabase/supabase-js";// these can come from an environment variable if desired// not required however as they are 100% exposed on the client side anyway // and that's ok, Supabase expects this (security is provided by Row Level Security)const supabaseUrl = "";const supabaseKey = "";// setup clientconst supabase = createClient(supabaseUrl, supabaseKey);// expose supabase clientexport default function useSupabase() {  return { supabase };}2
登录后复制

最后,我们将注册这个路由。

// UseSupabase.jsimport { createClient } from "@supabase/supabase-js";// these can come from an environment variable if desired// not required however as they are 100% exposed on the client side anyway // and that's ok, Supabase expects this (security is provided by Row Level Security)const supabaseUrl = "";const supabaseKey = "";// setup clientconst supabase = createClient(supabaseUrl, supabaseKey);// expose supabase clientexport default function useSupabase() {  return { supabase };}3
登录后复制

现在,点击登录页面上的 "忘记密码?"链接将把你带到这里。

Me.vue

我们需要的最后一个页面是一个个人资料页面,在用户登录后显示他们的秘密信息。我们将它称为/me

// UseSupabase.jsimport { createClient } from "@supabase/supabase-js";// these can come from an environment variable if desired// not required however as they are 100% exposed on the client side anyway // and that's ok, Supabase expects this (security is provided by Row Level Security)const supabaseUrl = "";const supabaseKey = "";// setup clientconst supabase = createClient(supabaseUrl, supabaseKey);// expose supabase clientexport default function useSupabase() {  return { supabase };}4
登录后复制

我们还将添加路由中间件,让我们的程序知道这应该是一个受保护的路由,只有通过认证的用户才能访问。

// UseSupabase.jsimport { createClient } from "@supabase/supabase-js";// these can come from an environment variable if desired// not required however as they are 100% exposed on the client side anyway // and that's ok, Supabase expects this (security is provided by Row Level Security)const supabaseUrl = "";const supabaseKey = "";// setup clientconst supabase = createClient(supabaseUrl, supabaseKey);// expose supabase clientexport default function useSupabase() {  return { supabase };}5
登录后复制

然后,为了让这个中间件真正发挥作用,我们需要这样来实现它。

// UseSupabase.jsimport { createClient } from "@supabase/supabase-js";// these can come from an environment variable if desired// not required however as they are 100% exposed on the client side anyway // and that's ok, Supabase expects this (security is provided by Row Level Security)const supabaseUrl = "";const supabaseKey = "";// setup clientconst supabase = createClient(supabaseUrl, supabaseKey);// expose supabase clientexport default function useSupabase() {  return { supabase };}6
登录后复制

页面本身将是一个简单的问候用户的信息。

// UseSupabase.jsimport { createClient } from "@supabase/supabase-js";// these can come from an environment variable if desired// not required however as they are 100% exposed on the client side anyway // and that's ok, Supabase expects this (security is provided by Row Level Security)const supabaseUrl = "";const supabaseKey = "";// setup clientconst supabase = createClient(supabaseUrl, supabaseKey);// expose supabase clientexport default function useSupabase() {  return { supabase };}7
登录后复制

我们现在还不会尝试查看这个页面,因为我们还没有实现登录。

https://github.com/danielkellyio/supabase-auth-example

现在,页面和AuthUser组合已经到位,我们可以开始通过调用Supabase SDK来填充AuthUser组合函数的内容。

我们需要做的第一件事是访问我们的Supabase客户端。要实现这一点,我们可以导入UseSupabase可组合函数,并从中解构Supabase客户端。

// UseSupabase.jsimport { createClient } from "@supabase/supabase-js";// these can come from an environment variable if desired// not required however as they are 100% exposed on the client side anyway // and that's ok, Supabase expects this (security is provided by Row Level Security)const supabaseUrl = "";const supabaseKey = "";// setup clientconst supabase = createClient(supabaseUrl, supabaseKey);// expose supabase clientexport default function useSupabase() {  return { supabase };}8
登录后复制

现在我们可以通过我们的空函数,一个一个地填充它们。

login()

为了登录Supabase,我们需要调用supabase.auth.signIn 。我们也可以等待响应,如果有错误就抛出一个新的错误,否则就返回登录的用户。

// UseSupabase.jsimport { createClient } from "@supabase/supabase-js";// these can come from an environment variable if desired// not required however as they are 100% exposed on the client side anyway // and that's ok, Supabase expects this (security is provided by Row Level Security)const supabaseUrl = "";const supabaseKey = "";// setup clientconst supabase = createClient(supabaseUrl, supabaseKey);// expose supabase clientexport default function useSupabase() {  return { supabase };}9
登录后复制loginWithSocialProvider()

loginWithSocialProvider也同样简单。只需要将提供者传递给signIn方法。

import { ref } from "vue";// user is set outside of the useAuthUser function// so that it will act as global state and always refer to a single userconst user = ref(null);export default function useAuthUser() {  /**   * Login with email and password   */  const login = async ({ email, password }) => {};  /**   * Login with google, github, etc   */  const loginWithSocialProvider = (provider) => {};  /**   * Logout   */  const logout = async () => {};  /**   * Check if the user is logged in or not   */  const isLoggedIn = () => {};  /**   * Register   */  const register = async ({ email, password, ...meta }) => {};  /**   * Update user email, password, or meta data   */  const update = async (data) => {};  /**   * Send user an email to reset their password   * (ie. support "Forgot Password?")   */  const sendPasswordRestEmail = async (email) => {};  return {    user,    login,    loginWithSocialProvider,    isLoggedIn,    logout,    register,    update,    sendPasswordRestEmail,    maybeHandleEmailConfirmation,  };}0
登录后复制logout()

要注销当前用户,我们需使用Supabase的signOut方法。由于用户不再可用,所以没有什么可以从注销中返回。

import { ref } from "vue";// user is set outside of the useAuthUser function// so that it will act as global state and always refer to a single userconst user = ref(null);export default function useAuthUser() {  /**   * Login with email and password   */  const login = async ({ email, password }) => {};  /**   * Login with google, github, etc   */  const loginWithSocialProvider = (provider) => {};  /**   * Logout   */  const logout = async () => {};  /**   * Check if the user is logged in or not   */  const isLoggedIn = () => {};  /**   * Register   */  const register = async ({ email, password, ...meta }) => {};  /**   * Update user email, password, or meta data   */  const update = async (data) => {};  /**   * Send user an email to reset their password   * (ie. support "Forgot Password?")   */  const sendPasswordRestEmail = async (email) => {};  return {    user,    login,    loginWithSocialProvider,    isLoggedIn,    logout,    register,    update,    sendPasswordRestEmail,    maybeHandleEmailConfirmation,  };}1
登录后复制isLoggedIn()

对于isLoggedIn函数,我们只需检查reactive ref user是否有一个值。

import { ref } from "vue";// user is set outside of the useAuthUser function// so that it will act as global state and always refer to a single userconst user = ref(null);export default function useAuthUser() {  /**   * Login with email and password   */  const login = async ({ email, password }) => {};  /**   * Login with google, github, etc   */  const loginWithSocialProvider = (provider) => {};  /**   * Logout   */  const logout = async () => {};  /**   * Check if the user is logged in or not   */  const isLoggedIn = () => {};  /**   * Register   */  const register = async ({ email, password, ...meta }) => {};  /**   * Update user email, password, or meta data   */  const update = async (data) => {};  /**   * Send user an email to reset their password   * (ie. support "Forgot Password?")   */  const sendPasswordRestEmail = async (email) => {};  return {    user,    login,    loginWithSocialProvider,    isLoggedIn,    logout,    register,    update,    sendPasswordRestEmail,    maybeHandleEmailConfirmation,  };}2
登录后复制

如果你在想,我们在登录用户时从来没有设置过这个值,你是完全正确的,但我们将利用另一个小的supabase方法来帮助我们解决这个问题,就在一分钟之内。

register()

register函数与login函数几乎相同,都需要输入电子邮件和密码。然而,它也需要接受其他用户信息(即元数据)。我们将重定向到个人资料页面,并附带查询变量,包含一些有用信息。

import { ref } from "vue";// user is set outside of the useAuthUser function// so that it will act as global state and always refer to a single userconst user = ref(null);export default function useAuthUser() {  /**   * Login with email and password   */  const login = async ({ email, password }) => {};  /**   * Login with google, github, etc   */  const loginWithSocialProvider = (provider) => {};  /**   * Logout   */  const logout = async () => {};  /**   * Check if the user is logged in or not   */  const isLoggedIn = () => {};  /**   * Register   */  const register = async ({ email, password, ...meta }) => {};  /**   * Update user email, password, or meta data   */  const update = async (data) => {};  /**   * Send user an email to reset their password   * (ie. support "Forgot Password?")   */  const sendPasswordRestEmail = async (email) => {};  return {    user,    login,    loginWithSocialProvider,    isLoggedIn,    logout,    register,    update,    sendPasswordRestEmail,    maybeHandleEmailConfirmation,  };}3
登录后复制

请注意这个很酷的小技巧,我们把meta:...meta 。这允许我们在调用函数时,在传递给函数的对象中提供同一层次的元数据,但在函数中单独访问它。

import { ref } from "vue";// user is set outside of the useAuthUser function// so that it will act as global state and always refer to a single userconst user = ref(null);export default function useAuthUser() {  /**   * Login with email and password   */  const login = async ({ email, password }) => {};  /**   * Login with google, github, etc   */  const loginWithSocialProvider = (provider) => {};  /**   * Logout   */  const logout = async () => {};  /**   * Check if the user is logged in or not   */  const isLoggedIn = () => {};  /**   * Register   */  const register = async ({ email, password, ...meta }) => {};  /**   * Update user email, password, or meta data   */  const update = async (data) => {};  /**   * Send user an email to reset their password   * (ie. support "Forgot Password?")   */  const sendPasswordRestEmail = async (email) => {};  return {    user,    login,    loginWithSocialProvider,    isLoggedIn,    logout,    register,    update,    sendPasswordRestEmail,    maybeHandleEmailConfirmation,  };}4
登录后复制update()

尽管我们没有提供更新用户接口,但是通过Supabase,我们可以轻松实现这个函数。

import { ref } from "vue";// user is set outside of the useAuthUser function// so that it will act as global state and always refer to a single userconst user = ref(null);export default function useAuthUser() {  /**   * Login with email and password   */  const login = async ({ email, password }) => {};  /**   * Login with google, github, etc   */  const loginWithSocialProvider = (provider) => {};  /**   * Logout   */  const logout = async () => {};  /**   * Check if the user is logged in or not   */  const isLoggedIn = () => {};  /**   * Register   */  const register = async ({ email, password, ...meta }) => {};  /**   * Update user email, password, or meta data   */  const update = async (data) => {};  /**   * Send user an email to reset their password   * (ie. support "Forgot Password?")   */  const sendPasswordRestEmail = async (email) => {};  return {    user,    login,    loginWithSocialProvider,    isLoggedIn,    logout,    register,    update,    sendPasswordRestEmail,    maybeHandleEmailConfirmation,  };}5
登录后复制sendPasswordResetEmail()

最后一个要实现的函数是sendPasswordResetEmail 。再一次,supabase有一个简单的解决方案。

import { ref } from "vue";// user is set outside of the useAuthUser function// so that it will act as global state and always refer to a single userconst user = ref(null);export default function useAuthUser() {  /**   * Login with email and password   */  const login = async ({ email, password }) => {};  /**   * Login with google, github, etc   */  const loginWithSocialProvider = (provider) => {};  /**   * Logout   */  const logout = async () => {};  /**   * Check if the user is logged in or not   */  const isLoggedIn = () => {};  /**   * Register   */  const register = async ({ email, password, ...meta }) => {};  /**   * Update user email, password, or meta data   */  const update = async (data) => {};  /**   * Send user an email to reset their password   * (ie. support "Forgot Password?")   */  const sendPasswordRestEmail = async (email) => {};  return {    user,    login,    loginWithSocialProvider,    isLoggedIn,    logout,    register,    update,    sendPasswordRestEmail,    maybeHandleEmailConfirmation,  };}6
登录后复制观察Auth状态的变化

我们已经接近开始使用接口的阶段,但还需完成一个关键步骤。我们需要知道用户何时登录或注销,并相应地更新AuthUser组合中的反应式ref。

有时候,在登录和注销方法中实现这个任务可能是可行的,这可能是你首先想到的解决方案。然而,如果用户因为会话过期而注销了呢?或者如果用户在Supabase那边被更新或删除了呢?在这两种情况下,我们的登录和注销方法都不会被调用。

为了解决这个问题,Supabase提供了一个叫做onAuthStateChange 的函数。

我们可以在我们的supabase组合中调用这个函数,让它监听auth状态的所有变化,然后相应地设置我们的用户reactive ref。

import { ref } from "vue";// user is set outside of the useAuthUser function// so that it will act as global state and always refer to a single userconst user = ref(null);export default function useAuthUser() {  /**   * Login with email and password   */  const login = async ({ email, password }) => {};  /**   * Login with google, github, etc   */  const loginWithSocialProvider = (provider) => {};  /**   * Logout   */  const logout = async () => {};  /**   * Check if the user is logged in or not   */  const isLoggedIn = () => {};  /**   * Register   */  const register = async ({ email, password, ...meta }) => {};  /**   * Update user email, password, or meta data   */  const update = async (data) => {};  /**   * Send user an email to reset their password   * (ie. support "Forgot Password?")   */  const sendPasswordRestEmail = async (email) => {};  return {    user,    login,    loginWithSocialProvider,    isLoggedIn,    logout,    register,    update,    sendPasswordRestEmail,    maybeHandleEmailConfirmation,  };}7
登录后复制

我选择在UseSupabase.js中的函数调用之外做这件事,这样它就只被调用一次,并与其他Supabase设置代码组织在一起。

测试东西

现在到了关键时刻。我们应该有大部分的工作。(尽管你马上就会看到,我们还需要再做一些调整)。在你的浏览器中导航到注册页面并注册。

之后,你应该成功地被重定向到EmailConfirmation页面,你的电子邮件地址显示在信息中。

另外,如果你检查你的收件箱,你会像预期那样收到电子邮件。

顺便提一下,如果你想定制这封电子邮件的样子,你可以在Supabase仪表板上的Authentication > Templates

另外,如果你在Authentication > Users ,你就可以看到你的新注册用户的状态是:Waiting for Verication!

很好,现在去点击电子邮件中的那个链接吧。哦,天哪!我们被重新定向到了一个新的网站。我们被重定向到了登录页面......这不对。请注意,确实在标题右上方的链接上写有“注销”

如果我们点击到me 页面,它将让我们访问它,并正确显示我们在注册表格中提供的名字。

问题是,在我们点击页面的那一瞬间,我们的中间件正在运行,我们还没有完全登录,因此authStateChange还没有发生,还没有设置我们的用户反应式。

让我们在我们的中间件中做一个例外,如果查询变量fromEmail存在,我们就继续让导航通过,因为我们知道,从确认邮件中来,用户将立即登录。

import { ref } from "vue";// user is set outside of the useAuthUser function// so that it will act as global state and always refer to a single userconst user = ref(null);export default function useAuthUser() {  /**   * Login with email and password   */  const login = async ({ email, password }) => {};  /**   * Login with google, github, etc   */  const loginWithSocialProvider = (provider) => {};  /**   * Logout   */  const logout = async () => {};  /**   * Check if the user is logged in or not   */  const isLoggedIn = () => {};  /**   * Register   */  const register = async ({ email, password, ...meta }) => {};  /**   * Update user email, password, or meta data   */  const update = async (data) => {};  /**   * Send user an email to reset their password   * (ie. support "Forgot Password?")   */  const sendPasswordRestEmail = async (email) => {};  return {    user,    login,    loginWithSocialProvider,    isLoggedIn,    logout,    register,    update,    sendPasswordRestEmail,    maybeHandleEmailConfirmation,  };}8
登录后复制

还要注意,这不是一个安全问题。如果有人在没有登录的情况下随意在查询字符串中包括fromEmail ,由于用户不存在,反正什么都不会显示出来,也不会从Supabase收到关于用户的信息。

注销

现在除了注销链接外,一切都应该正常了。通过为注销路由定义一个路由守卫并直接添加路由保护,我们可以使其正常工作。

import { ref } from "vue";// user is set outside of the useAuthUser function// so that it will act as global state and always refer to a single userconst user = ref(null);export default function useAuthUser() {  /**   * Login with email and password   */  const login = async ({ email, password }) => {};  /**   * Login with google, github, etc   */  const loginWithSocialProvider = (provider) => {};  /**   * Logout   */  const logout = async () => {};  /**   * Check if the user is logged in or not   */  const isLoggedIn = () => {};  /**   * Register   */  const register = async ({ email, password, ...meta }) => {};  /**   * Update user email, password, or meta data   */  const update = async (data) => {};  /**   * Send user an email to reset their password   * (ie. support "Forgot Password?")   */  const sendPasswordRestEmail = async (email) => {};  return {    user,    login,    loginWithSocialProvider,    isLoggedIn,    logout,    register,    update,    sendPasswordRestEmail,    maybeHandleEmailConfirmation,  };}9
登录后复制

注销后,如果你愿意,你可以尝试用不同的电子邮件再次注册,以确认我们上面的修复对直接导航到个人资料页面起作用。同样,当注销后,检查一下登录页面。你应该也能用现有的用户成功登录!

以上就是Vue3中如何使用Supabase Auth方法的详细内容,更多请关注9543建站博客其它相关文章!

广告:SSL证书一年128.66元起,点击购买~~~

9543建站博客
一个专注于网站开发、微信开发的技术类纯净博客。

作者头像
admin创始人

肥猫,知名SEO博客站长,14年SEO经验。

上一篇:JavaScript事件循环同步任务与异步任务
下一篇:css的颜色设置

发表评论

关闭广告
关闭广告