在2023年构建无服务器应用程序的最佳平台
#javascript #react #serverless

Supabase一个标记为“开源燃料杀手”的项目是Firebase的开源替代品。来自Google的SAS平台。 Supabase(例如Firebase)是SAS平台。 Supabase为您提供后端,以通过与应用程序的前端保持联系,使您能够完全专注于提供良好的用户体验,以实现快速应用程序开发。

每个Supabase项目都有一个完整的Postgres database,已经为您配置的身份验证服务,云存储API,访问Edge功能以及AI的矢量数据库。我们可以看到,Supabase的产品紧凑,与Firebase提供的产品相似,因此在今天的文章中,我将向您展示如何设置和集成Supabase身份验证到您的无服务器应用程序中。然后,我们将查看使用这种方法带来的一些好处,最后,我们看看这是否应该考虑。

在本文中,我将使用带有Vite生成的react app,我们将把讨论分解为以下标题;

  • 创建一个React项目。
  • supabase Integration
  • supabse auth的利弊
  • 您应该考虑吗?

创建一个React项目

我们将要创建的React项目将使用Vite生成,因此继续运行以下命令以生成新的Vite项目。

$ npm create vite@latest --template react

按照命令行中的提示生成您的应用程序,让我们继续并将以下组件添加到React应用程序中。让我们先创建一个登录页面组件。

// login.jsx

import { useState } from 'react';

const Login = () => {

  const [email, updateEmail] = useState();
  const [password, updatePassword] = useState();

  return (
    <form>
      <div>
        <label>Email</label>
        <input 
          value={email} 
          type="email"
          onChange={e => updateEmail(e.target.value)}
          placeholder="Johndoe@gmail.com"
          />
      </div>
      <div>
        <label>Password</label>
        <input 
          value={password} 
          type="password"
          onChange={e => updatePassword(e.target.value)}
          placeholder="*****"
          />
      </div>
      <div>
        <button>Login</button>
      </div>
    </form>
  );
};

export default Login;

让我们创建一个将是我们的注册页面的第二个组件。

// signup.jsx

import { useState } from 'react';

const Signup = () => {

  const [email, updateEmail] = useState();
  const [password, updatePassword] = useState();

  return (
    <form>
       <h3>Create a new account</h3>
      <div>
        <label>Email</label>
        <input 
          value={email} 
          type="email"
          onChange={e => updateEmail(e.target.value)}
          placeholder="Johndoe@gmail.com"
          />
      </div>
      <div>
        <label>Password</label>
        <input 
          value={password} 
          type="password"
          onChange={e => updatePassword(e.target.value)}
          placeholder="*****"
          />
      </div>
      <div>
        <button>Create Account</button>
      </div>
    </form>
  );
};

export default Signup;

现在,让我们创建最后一个组件,这将是仪表板,但我会尽可能简单。

// dashboard.jsx

const Dashboard = () => {
   return (
     <div>
       <h3>Welcome back</h3>
     </div>
  );
};

export default Dashboard;

现在,我们有一个React项目,让我们继续使用以下命令安装React-Router-Dom;

$ npm i react-router-dom

编辑App.jsx文件并将其粘贴到以下内容中。

import { createBrowserRouter} from "react-router-dom";
import { RouterProvider } from "react-router"
import Dashboard from "./dashboard";
import Login from "./login";
import Signup from "./signup";

const router = createBrowserRouter([
  {
    path: "/",
    element: (<Signup />),
  },  
  {
    path: "/login",
    element: <Login />
  },
  {
    path: "/dashboard",
    element: <Dashboard />
  }
]);

const App = () => (
  <RouterProvider router={router} />
);

那是模板都被刷掉的不是光滑,但肯定会完成。现在让我们设置Supabase集成。

supabase集成

首先,我们需要使用以下命令安装supabase,请确保;

  • 您访问了主页,并且还成功地使用了Supabase。
  • ,您的Supabase项目启动并运行。
$ npm install @supabase/supabase-js

现在,创建一个.envfile,您将在Supabase上放置一些代币以进行身份​​验证,转到Supabase Project dashboard单击设置,然后选择API,请确保复制项目URL和ANON密钥。打开您的.env文件并将这些值粘贴到。

VITE_PROJECT_URL=PROJECT_URL
VITE_ANON_KEY = ANON_KEY

现在,让我们在src文件夹中创建一个模块,该模块将容纳用于与Supabase客户端交互的助手功能。让我们称此文件helper.js。然后,让我们继续设置用于创建新用户帐户的功能

// helper.js

const PROJECT_URL = import.meta.env.VITE_PROJECT_URL
const ANON_KEY = import.meta.env.VITE_ANON_KEY

const supabase = createClient(PROJECT_URL, ANON_KEY)

export async function signInWithEmail({email, password}) {
  try {
    const { data, error } = await supabase.auth.signUp({
      email,
      password,
    })
    if (error) throw error
    return [null, data]
  } catch (error) {
    return [error, null]
  }
}

我们有一个功能,可以在用户中签名其电子邮件地址和密码。首先,我们使用createClient()函数创建一个新的客户端对象。 createClient()函数的第一个参数是项目URL,第二个参数是anon键。 Anon密钥是一个特殊的密钥,可用于访问Supabase项目中的公共数据。

然后,函数调用auth.signup()方法以注册用户。 Auth.Signup()方法采用两个参数:电子邮件地址和密码。 Auth.Signup()方法返回具有两个属性的对象:数据和错误。数据属性包含有关用户的数据,并且错误属性包含发生的任何错误。

该功能然后检查是否存在错误。如果存在错误,则该功能会引发错误。否则,该功能返回有关用户的数据。

让我们添加两个函数一个以登录到现有用户,最后一个从supabase检索用户及其相关的会话。

// helper.js continues

export async function login({email, password}) {
  try {
    const { data, error } = await supabase.auth.signInWithPassword({
      email,
      password,
    })
    if (error) throw error
    return [null, data]
  } catch (error) {
    return [error, null]
  }
}

export async function getCurrentUser(access_token) {
  try {
    const { data } = await supabase.auth.getUser(access_token)
    return [null, data.user];
  } catch (error) {
    console.log(error)
    return [error, null]
  }
}

现在让我们更新组件,以便我们的应用程序连接到Supabase,从注册页面开始

// signup.jsx
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';

const Signup = () => {

const navigate = useNavigate ()

const signup = async (e, _user) => {
    e.preventDefault()
    try {
      const [error, data] = await signInWithEmail(_user);
      if(error) throw error;
      alert('Account created successfully, please verify email')
      const {access_token, refresh_token} = data.session
      sessionStorage.setItem('access_token', access_token);
      sessionStorage.setItem('refresh_token', refresh_token);
      navigate('/dashboard')
    } catch (error) {
      console.log(error)
    }
  }

  const [email, updateEmail] = useState();
  const [password, updatePassword] = useState();

  return (
    <form 
       onSubmit={e => signup(e, {email, password} )}
    >
      // continued...
    </form>
  );
};

该组件定义一个称为Ingup()的函数。 INBISUP()函数采用两个参数:事件对象和一个带有用户的电子邮件地址和密码的对象。 Ingeup()函数调用signWitheMail()函数以注册用户。如果注册成功,则INGUP()函数会提醒用户并将其重定向到仪表板页面。如果注册未成功,则INGUP()函数将记录错误。

SessionStorage对象用于存储由SignWitheMail()函数返回的访问令牌和刷新令牌。访问令牌用于用supabase对用户进行身份验证,如果旧的,则使用刷新令牌来获得新的访问令牌。让我们在登录页面上做同样的事情。

// login.jsx

import { useState } from 'react';
import { useNavigate } from 'react-router-dom';

const Login = () => {

  const navigate = useNavigate();

  const [email, updateEmail] = useState();
  const [password, updatePassword] = useState();

  const login = async (e, _user) => {
    e.preventDefault();
    try {
      const [error, data] = await SignInWithEmail(_user);
      if(error) throw error
      alert('Log in successful')
      const {access_token, refresh_token} = data.session
      sessionStorage.setItem('access_token', access_token);
      sessionStorage.setItem('refresh_token', refresh_token);
      navigate("/dashboard", { replace: true });
    } catch (error) {
      if (error.message.includes('Email not confirmed')) alert('Please verify your email')
    }
  }


  return (
    <form 
       onSubmit={e => login(e, { email, password })}
    >
        // continued...
    </form>
  );
};

最后,让我们为仪表板页面做同样的事情。

// dashboard.jsx

import { useEffect, useState } from 'react'

const Dashboard = () => {

   const [currentUser, updateUser] = useState()
   useEffect(() => {
      const [error, user] = await getCurrentUser(sessionStorage.getItem('access_token'));
    if (error) console.log(error);
    if (user) updateUser(user)
   }, [])
   return (
     <div>
       <h3>Welcome back</h3>
     </div>
  );
};

export default Dashboard;

这就是我们的整合完成并建立了,让我们考虑使用这种方法的利弊。

Supabse Auth的优点

  • 它减少了您的整体发展时间并提高了您的生产力。
  • 他们的API很容易与之互动和理解。正如您所观察到的那样,我在设置这个项目方面并不挣扎。
  • 他们有一个免费的层

Supabse Auth的缺点

  • 您无法控制系统,总会有被锁定的危险。
  • 将现有用户移植到另一个平台并不是一个简单的过程。

你应该使用它吗?

如果您想创建一些只是为了娱乐或放在投资组合而不付钱的情况下创建一些东西,那么您应该尝试一下。如果您有钱可以花钱,并且您想建立一家1亿美元的科技公司,那么您也应该使用Supabase,可以节省大量的开发时间,并从您的团队中获得更多。

我是Firebase的忠实拥护者,因此,我对尝试和使用Supabase非常怀疑,但是自从我测试它以来,我就开始欣赏使用Supabase的感觉。尝试一下,留下您对supabase的想法,并放弃与Supabase合作的经验,我将在下一篇文章中与您见面。