尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

现代全栈开发环境搭建:Next.js + Supabase + Resend + Stripe 实战指南

现代全栈开发环境搭建:Next.js + Supabase + Resend + Stripe 实战指南 1. 项目概述构建一个现代化的全栈应用开发环境最近在折腾一个全栈项目核心目标是搭建一个集成了现代前端框架、强大的后端即服务BaaS、可靠的邮件服务以及安全支付功能的开发环境。这个配置方案特别适合独立开发者或小团队快速启动一个具备生产级能力的应用原型比如内容平台、SaaS工具或者社区应用。我选择的工具链是Next.js TypeScript Tailwind CSS作为前端基础用Supabase处理数据库、认证和存储用Resend搞定邮件发送支付则交给Stripe。整个开发流程的核心辅助工具是Cursor它基于 Claude 模型能极大提升在复杂技术栈下的开发效率。这篇文章我就来详细拆解这套环境从零到一的搭建过程、每个环节的配置要点以及我踩过的一些坑和总结的经验。2. 核心工具链选型与设计思路2.1 为什么选择这套技术栈在启动一个全栈项目时技术选型决定了后续的开发体验和项目的可维护性。我选择的这套组合是在平衡了开发效率、学习成本、社区生态和长期可扩展性之后的结果。前端Next.js TypeScript Tailwind CSS shadcn/uiNext.js 提供了开箱即用的服务端渲染SSR、静态生成SSG和 API Routes这对于需要良好SEO和性能的现代Web应用几乎是首选。TypeScript 的静态类型检查能在开发阶段就避免大量低级错误尤其是在与后端API交互时类型安全至关重要。Tailwind CSS 的实用类优先Utility-First理念极大地加速了UI开发避免了传统CSS中样式命名和管理的痛苦。而shadcn/ui不是一个传统的组件库它是一套基于 Radix UI 构建的、可复制粘贴到项目中的高质量组件代码。这意味着你拥有组件的完全控制权可以随意修改源码以适应设计需求同时又避免了从零开始构建通用组件如对话框、下拉菜单的重复劳动。后端与数据层SupabaseSupabase 是开源的 Firebase 替代品提供了 PostgreSQL 数据库、实时订阅、身份认证、存储和边缘函数等一系列服务。选择它主要基于几点首先它直接使用 PostgreSQL这是一个功能极其强大且可靠的关系型数据库避免了被供应商锁定的风险你可以随时导出数据。其次它的身份认证系统非常完善支持多种第三方OAuth提供商如GitHub、Google以及邮箱密码登录并且与数据库的行级安全RLS策略无缝集成能轻松实现数据访问权限控制。最后它的存储服务对于处理用户上传的文件如图片、文档非常方便。邮件服务Resend应用中的事务性邮件如注册确认、密码重置、通知必须可靠。Resend 是一个为开发者设计的邮件API服务它提供了优秀的开发者体验、清晰的日志、以及基于React的邮件模板构建能力。相比自己搭建SMTP服务器或使用一些配置复杂的传统服务Resend 与 Next.js 等现代框架的集成更简单送达率也更有保障。支付Stripe对于处理在线支付Stripe 是行业标杆。它提供了极其完善的API、清晰的管理面板、丰富的预构建UI组件如Checkout以及强大的订阅管理功能。其安全性、合规性都由 Stripe 团队处理大大减轻了开发者的负担。开发助手CursorCursor 是一个集成了AI默认是Claude 3系列模型的代码编辑器。在配置这种多服务集成的项目时你需要频繁查阅不同服务的文档、编写配置代码、调试环境变量。Cursor 的“Chat”和“Edit”功能可以让你通过自然语言快速生成代码片段、解释错误信息、甚至重构代码能显著减少在文档和编辑器之间切换的时间。2.2 环境隔离策略开发与生产一个关键的设计原则是从一开始就严格区分开发环境和生产环境。这能避免用生产数据库进行测试的灾难性错误也能让配置管理更清晰。Supabase 项目我会创建两个独立的 Supabase 项目一个用于开发例如myapp-dev一个用于生产myapp-prod。它们拥有完全独立的数据、存储桶和认证配置。GitHub OAuth 应用同样在 GitHub 上注册两个 OAuth Application分别指向开发环境http://localhost:3000和生产环境https://myapp.com的回调地址。环境变量使用.env.local开发和.env.production生产来管理所有服务的API密钥、URL等敏感信息。Next.js 内置了对这些环境文件的支持。Resend 与 Stripe这些服务通常提供测试模式Test Mode和直播模式Live Mode。开发时使用测试模式的API密钥可以模拟支付和发送邮件而不会产生实际费用或发送真实邮件。3. 前端工程初始化与UI组件库搭建3.1 创建Next.js项目并配置基础依赖首先我们使用 Next.js 的官方工具创建一个 TypeScript 项目。打开终端执行以下命令npx create-next-applatest my-app --typescript --tailwind --app --no-eslint这里有几个参数需要解释一下--typescript和--tailwind直接集成 TypeScript 和 Tailwind CSS。--app表示使用 Next.js 13 推荐的 App Router 结构它比旧的 Pages Router 提供了更精细的布局控制和数据获取能力。--no-eslint是可选的我个人在初期快速原型阶段会先关闭严格的 ESLint 检查以加快进度等项目结构稳定后再开启。进入项目目录并安装一些后续会用到的基础库cd my-app npm install clsx tailwind-merge lucide-reactclsx和tailwind-merge是用于条件化合并 CSS 类名的工具在构建动态组件时非常有用。lucide-react提供了一套简洁美观的图标组件。3.2 集成与配置 shadcn/uishadcn/ui 的集成非常独特它不是通过npm install来安装的而是通过一个 CLI 工具将组件源码直接添加到你的项目中。这确保了你可以完全控制组件样式。首先初始化 shadcn/ui。这个命令会创建一个components.json配置文件并询问你一些偏好设置。npx shadcnlatest init执行后CLI 会交互式地询问几个问题我的选择如下Which style would you like to use?›New York“New York” 风格提供了一种更圆润、间距更宽松的视觉设计我个人觉得比默认的“Default”风格更现代。Which color would you like to use as base color?›ZincZinc 是一种中性灰色系作为基础色非常百搭易于在此基础上构建品牌色。Do you want to use CSS variables for colors?›yes强烈建议选择“是”。这会将颜色主题定义为 CSS 变量如--primary让你可以在tailwind.config.ts中一键切换整个应用的配色方案比如从浅色模式切换到深色模式会变得非常简单。初始化完成后就可以开始添加具体的组件了。根据项目需求我首先添加了最常用的几个基础组件npx shadcnlatest add button npx shadcnlatest add input npx shadcnlatest add card npx shadcnlatest add tabs每个add命令都会做以下几件事从 shadcn/ui 的源码仓库下载该组件的 React 代码TSX、样式代码以及必要的依赖项如radix-ui/react-tabs。将这些文件放置在你项目根目录下的/components/ui/文件夹中例如button.tsx,input.tsx。自动在package.json中安装该组件所需的第三方底层库通常是 Radix UI 的对应组件。现在你就可以像使用自己编写的组件一样从/components/ui导入并使用这些高度定制化的 UI 元素了。所有样式都基于你的tailwind.config.ts和 CSS 变量确保了视觉一致性。实操心得在add组件时有时会因为网络问题或版本冲突导致失败。如果遇到问题可以尝试先清理缓存npx shadcnlatest clean或者直接去 shadcn/ui 的官网文档找到对应组件的代码手动复制到你的components/ui目录下。手动复制时要注意同时复制相关的依赖项。4. 后端即服务Supabase 项目配置详解4.1 创建与管理多环境项目前往 Supabase Dashboard 并登录。点击“New project”。在创建表单中需要仔细填写以下信息Organization选择你的组织。如果你是个人使用通常就是你的账户名。Project name为你的开发环境项目起一个清晰的名字例如myapp-dev。名字中最好包含环境标识。Database Password为你的 PostgreSQL 数据库设置一个强密码。务必妥善保存此密码虽然 Supabase 提供了连接字符串但某些高级管理工具可能仍需密码。可以直接点击“Generate a password”让系统生成一个。Region选择离你的目标用户最近或你所在地区的区域。例如如果你的用户主要在亚洲选择“Northeast Asia (Tokyo)”能获得更低的网络延迟。注意一旦创建区域无法更改。点击“Create new project”。Supabase 会花几分钟时间初始化你的项目包括数据库、API 网关、认证服务等。重要请完全按照上述流程再创建一个独立的项目用于生产环境例如命名为myapp-prod。两个项目的密码、区域都可以根据实际情况设置成不同的。4.2 获取项目连接信息与配置环境变量项目创建成功后进入项目仪表板。在左侧边栏找到Project Settings然后选择API标签页。这个页面包含了连接你的 Next.js 应用所需的所有关键信息Project URL你的 Supabase API 的根地址格式为https://project-ref.supabase.co。这个project-ref是项目的唯一标识符。anon/public key这个密钥用于客户端浏览器代码中。它被设计为可以安全地暴露在前端与 Row Level Security (RLS) 策略协同工作控制数据访问权限。service_role key这是一个超级密钥必须绝对保密永远不要暴露给前端它仅在安全的服务器端环境如 Next.js 的 API Route、Server Action 或中间件中使用可以绕过 RLS 策略。泄露此密钥等同于将数据库完全开放。在你的 Next.js 项目根目录下创建或编辑.env.local文件添加以下变量# .env.local NEXT_PUBLIC_SUPABASE_URLhttps://your-project-ref.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEYyour-anon-key SUPABASE_SERVICE_ROLE_KEYyour-service-role-key # 注意没有 NEXT_PUBLIC_ 前缀注意事项NEXT_PUBLIC_前缀是 Next.js 的约定表示这个变量可以在浏览器端代码中被访问。SUPABASE_SERVICE_ROLE_KEY没有这个前缀因此它只在 Node.js 运行时服务器端可用这提供了基本的安全保障。4.3 配置 GitHub OAuth 提供商开发环境为了让用户能够使用 GitHub 账号登录我们需要在 GitHub 上注册一个 OAuth App并将其配置到 Supabase 的认证系统中。第一步在 GitHub 创建 OAuth App登录 GitHub点击右上角头像进入Settings。在左侧边栏底部找到Developer settings然后进入OAuth Apps。点击“Register a new application”。填写应用信息Application name:MyApp Dev(明确标识是开发环境)Homepage URL:http://localhost:3000(你的本地开发服务器地址)Authorization callback URL: 这里先留空我们稍后从 Supabase 获取。点击“Register application”。创建成功后你会看到Client ID和Client secrets。点击“Generate a new client secret”来生成一个密钥。请立即复制并保存好 Client ID 和 Client Secret因为 Secret 只显示一次。第二步在 Supabase 中配置 GitHub 提供商回到你的myapp-devSupabase 项目仪表板。进入Authentication-Providers。找到GitHub提供商点击它展开配置。你会看到一个Redirect URL格式为https://project-ref.supabase.co/auth/v1/callback。复制这个 URL。回到刚才 GitHub OAuth App 的配置页面将复制的 Redirect URL 粘贴到Authorization callback URL字段中并保存。将 GitHub 生成的Client ID和Client Secret分别填入 Supabase 中 GitHub 提供商的对应字段。将GitHub enabled开关打开。点击Save。现在你的开发环境应用就已经支持 GitHub 登录了。生产环境的配置流程完全一样只是需要创建另一个 GitHub OAuth App其Homepage URL和Callback URL都使用你的生产域名如https://myapp.com。5. 邮件服务集成使用 Resend 配置自定义 SMTPSupabase 的认证服务在用户注册、重置密码等场景下需要发送邮件。虽然 Supabase 提供了默认的邮件服务但可能有限制或品牌标识。使用 Resend 作为自定义 SMTP 服务器可以获得更高的可靠性和自定义发件人信息。5.1 注册 Resend 并验证域名访问 Resend 并注册账号。进入 Dashboard点击“Add Domain”。Resend 要求你使用一个已验证的域名来发送邮件以确保发件人信誉。你可以使用你的应用主域名如myapp.com或一个子域名如mail.myapp.com。添加域名后Resend 会提供一组 DNS 记录主要是 TXT 和 MX 记录。你需要到你的域名注册商如 Cloudflare, GoDaddy的 DNS 管理页面添加这些记录。验证过程可能需要几分钟到几小时。域名验证成功后在API Keys页面点击“Create API Key”生成一个新的 API 密钥。这个密钥将作为 SMTP 密码使用。5.2 在 Supabase 中配置 Resend SMTP进入你的 Supabase 项目开发环境和生产环境需要分别配置。导航至Project Settings-Authentication-SMTP Settings。将Enable Custom SMTP开关打开。根据 Resend 的 SMTP 文档 填写以下信息Sender email: 发件人邮箱地址。必须是你已验证域名下的邮箱例如noreplymail.myapp.com。Resend 不允许使用通用邮箱如 gmail.com。Sender name: 发件人显示名称例如MyApp Team。Host:smtp.resend.comPort:465(使用 SSL) 或587(使用 STARTTLS)。这里推荐465。Username:resendPassword: 填入你在 Resend 生成的API Key。填写完毕后可以点击“Send test email”来验证配置是否正确。输入一个你的个人邮箱地址如果收到测试邮件说明配置成功。最后点击Save。重要提示Supabase 的 SMTP 配置是项目级别的。这意味着一旦启用该项目所有通过 Supabase Auth 触发的邮件如确认邮件、密码重置邮件、Magic Link 等都将通过你配置的 Resend SMTP 服务器发送。请确保在生产环境项目中使用生产域名的 Resend 配置。6. 在 Next.js 应用中集成 Supabase 客户端6.1 安装 Supabase 客户端库在 Next.js 项目根目录下安装 Supabase 的 JavaScript 客户端库npm install supabase/supabase-js6.2 创建 Supabase 客户端工具函数为了在客户端和服务器端都能方便地创建 Supabase 客户端实例我们通常在项目中创建一个工具文件。在项目根目录创建lib/supabase.ts// lib/supabase.ts import { createClient } from supabase/supabase-js // 从环境变量中读取URL和匿名密钥这些是公开的 const supabaseUrl process.env.NEXT_PUBLIC_SUPABASE_URL! const supabaseAnonKey process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY! // 检查环境变量是否存在 if (!supabaseUrl || !supabaseAnonKey) { throw new Error(Missing Supabase environment variables) } // 创建并导出一个供客户端组件使用的 Supabase 客户端 // 这个客户端使用匿名密钥权限受 RLS 策略限制 export const supabase createClient(supabaseUrl, supabaseAnonKey) // 可选创建一个用于服务器端操作的客户端使用服务角色密钥 // 注意这个函数只能在服务器端运行如在 API Route、Server Action 或 Server Component 中 import { cookies } from next/headers export async function createServerSupabaseClient() { const cookieStore cookies() // 这里可以传入从请求中获取的 cookies用于维持服务器端的认证状态 // 为了简化我们先创建一个使用服务角色密钥的客户端用于需要高权限的后台操作 const supabaseUrl process.env.NEXT_PUBLIC_SUPABASE_URL! const supabaseServiceKey process.env.SUPABASE_SERVICE_ROLE_KEY! if (!supabaseServiceKey) { throw new Error(Missing SUPABASE_SERVICE_ROLE_KEY environment variable) } return createClient(supabaseUrl, supabaseServiceKey, { auth: { persistSession: false, // 服务器端客户端通常不需要持久化会话 }, }) }6.3 实现 GitHub 登录功能接下来我们创建一个简单的登录页面来演示如何使用 Supabase 客户端进行 GitHub OAuth 登录。在app/login/page.tsx中// app/login/page.tsx use client // 这是一个客户端组件因为需要处理用户交互 import { Button } from /components/ui/button import { supabase } from /lib/supabase import { Github } from lucide-react export default function LoginPage() { const handleGitHubLogin async () { // 调用 signInWithOAuth 方法指定提供商为 github const { error } await supabase.auth.signInWithOAuth({ provider: github, options: { // 可以控制重定向行为这里让 Supabase 处理重定向 redirectTo: ${window.location.origin}/auth/callback, // 需要创建一个回调页面来处理登录后的逻辑 }, }) if (error) { console.error(GitHub login error:, error.message) // 在实际应用中这里应该给用户一个友好的错误提示 alert(Login failed: ${error.message}) } // 如果成功用户将被重定向到 GitHub 授权页面授权后回到指定的 callback URL } return ( div classNameflex min-h-screen items-center justify-center div classNamew-full max-w-md space-y-8 rounded-lg border p-8 shadow-lg div h2 classNamemt-6 text-center text-3xl font-boldSign in to your account/h2 /div Button onClick{handleGitHubLogin} classNamew-full variantoutline sizelg Github classNamemr-2 h-5 w-5 / Sign in with GitHub /Button /div /div ) }6.4 创建 OAuth 回调页面处理登录状态OAuth 流程完成后用户会被重定向回我们指定的回调地址。我们需要一个页面来接收授权码由 Supabase 客户端完成最终的会话交换并将用户重定向到应用主页。创建app/auth/callback/route.ts// app/auth/callback/route.ts import { createRouteHandlerClient } from supabase/auth-helpers-nextjs import { cookies } from next/headers import { NextResponse } from next/server import type { NextRequest } from next/server export async function GET(request: NextRequest) { const requestUrl new URL(request.url) const code requestUrl.searchParams.get(code) // 如果 URL 中有授权码则用其交换用户会话 if (code) { // 使用 Supabase 为 Next.js App Router 提供的辅助工具创建客户端 const supabase createRouteHandlerClient({ cookies }) await supabase.auth.exchangeCodeForSession(code) } // 登录成功后重定向用户到首页或其他受保护页面 return NextResponse.redirect(requestUrl.origin) }这个文件使用了supabase/auth-helpers-nextjs库它能更好地在 Next.js App Router 的服务器组件和路由处理器中管理认证状态和 cookies。你需要先安装它npm install supabase/auth-helpers-nextjs7. 数据库设计与行级安全策略配置7.1 通过 Supabase 仪表板创建表假设我们正在构建一个简单的“技术文章”分享平台需要一张articles表。进入 Supabase 项目仪表板的Table Editor点击“Create a new table”。Table name:articlesColumns:id(类型bigint, 主键自增)created_at(类型timestamptz, 默认值now())title(类型text, 非空)content(类型text)user_id(类型uuid, 关联auth.users表的id)点击Save创建表。user_id字段将用于关联文章的作者即登录用户。7.2 启用与配置行级安全策略创建表后Supabase 会自动提示你启用 Row Level Security (RLS)。RLS 是 Supabase 数据安全的核心务必为所有表启用。点击articles表旁边的开关启用 RLS。启用 RLS 后所有对该表的访问默认都会被拒绝。我们必须创建策略Policies来明确谁可以做什么。点击“Create a new policy”或使用 SQL 编辑器。这里我们创建三条策略查询策略Select允许所有人查看已发布的文章但只允许作者查看自己的草稿。插入策略Insert只允许认证用户创建文章并且自动将user_id设置为当前用户。更新/删除策略Update/Delete只允许文章的作者更新或删除自己的文章。我们可以使用 SQL 来创建这些策略更清晰也更有力。进入SQL Editor运行以下 SQL 语句-- 策略 1查询策略 -- 允许所有人查看所有文章假设所有文章都是公开的 -- 如果需要区分草稿和发布可以添加一个 published 布尔字段并修改策略 CREATE POLICY 任何人都可以查看文章 ON public.articles FOR SELECT USING ( true ); -- 无条件允许 SELECT -- 策略 2插入策略 -- 只允许认证用户插入并自动设置 user_id CREATE POLICY 认证用户可以创建文章 ON public.articles FOR INSERT WITH CHECK ( auth.uid() user_id ); -- 确保插入的 user_id 等于当前登录用户的ID -- 策略 3更新策略 -- 只允许作者更新自己的文章 CREATE POLICY 用户只能更新自己的文章 ON public.articles FOR UPDATE USING ( auth.uid() user_id ) WITH CHECK ( auth.uid() user_id ); -- 策略 4删除策略 -- 只允许作者删除自己的文章 CREATE POLICY 用户只能删除自己的文章 ON public.articles FOR DELETE USING ( auth.uid() user_id );关键点解析auth.uid()是一个 Supabase 提供的函数在 SQL 策略中调用时它会返回当前发出请求的用户的 UUID如果用户已认证。如果用户未登录则返回null。WITH CHECK子句用于INSERT和UPDATE操作它规定了新写入或修改后的行必须满足的条件。这对于INSERT时自动设置user_id至关重要。这些策略组合起来实现了基于用户的数据访问控制而无需在应用代码中编写复杂的权限判断逻辑。8. 使用 Cursor 提升全栈开发效率在配置上述复杂环境时一个强大的 AI 辅助工具能节省大量时间。Cursor 编辑器内置了 Claude 模型我主要通过两种方式使用它8.1 通过 Chat 进行上下文咨询当我不确定某个配置的具体步骤时例如“如何在 Supabase 中为articles表设置一个只允许作者更新自己文章的 RLS 策略”我会直接打开 Cursor 的 Chat 面板快捷键CmdK提问。Cursor 的优势在于它能“看到”我当前打开的文件和项目结构。我可以选中一段 SQL 代码或配置文件然后问它“这段代码是什么意思”或“如何优化这个策略”。它给出的解释和建议通常非常准确并且能结合我项目的具体上下文。8.2 使用 Edit 指令进行代码生成与重构这是 Cursor 最强大的功能之一。假设我正在编写前面提到的lib/supabase.ts文件但忘记了createClient的确切导入方式和参数。我可以直接写一个注释// Create a Supabase client for browser然后选中这行注释按下CmdK输入指令如“generate the client creation code using environment variables”。Cursor 会根据我已有的.env.local文件中的变量名生成非常准确的代码。另一个常用场景是重构。当我从 Supabase 仪表板复制了 RLS 策略的 SQL 后可能想把它整理成一个更规范的迁移文件。我可以选中这段 SQL用 Edit 指令“Convert this SQL into a Supabase migration file namedcreate_rls_policies_for_articles.sql”。Cursor 会生成一个格式正确、带有注释的 SQL 文件。实操心得虽然 Cursor 很强大但它不是万能的。对于关键的业务逻辑、安全相关的代码如 RLS 策略一定要在它生成的基础上进行仔细的人工审查和测试。把它看作一个超级智能的“结对编程”伙伴而不是一个全自动代码生成器。它的价值在于快速提供样板代码、解释复杂概念和发现常见错误模式。9. 常见问题与故障排查实录在搭建和集成这套技术栈的过程中我遇到了不少典型问题。这里记录下排查思路和解决方案希望能帮你绕过这些坑。9.1 认证相关错误问题GitHub OAuth 登录失败提示“Invalid OAuth credentials”或重定向 URI 不匹配。排查步骤 1检查 Supabase 中 GitHub 提供商的Client ID和Client Secret是否与 GitHub OAuth App 页面上的完全一致注意区分开发环境和生产环境的配置。排查步骤 2这是最常见的原因。确保 GitHub OAuth App 中设置的Authorization callback URL与 Supabase 提供的Redirect URL完全一致包括http与https、末尾的斜杠等。Supabase 的 Redirect URL 可以在Authentication - Providers - GitHub配置页面找到并复制。排查步骤 3检查你的 Next.js 应用在发起 OAuth 登录时传递的redirectTo选项是否与 Supabase 中配置的Site URL在Authentication - URL Configuration中属于同一个“域”。Supabase 出于安全考虑会验证重定向地址。问题用户登录后会话无法在客户端保持。排查步骤检查是否在客户端组件中正确使用了createClientComponentClient来自supabase/auth-helpers-nextjs或类似方法。确保没有在服务器组件中错误地创建客户端实例。另外检查 Next.js 中间件如果使用了是否正确处理了认证状态刷新。9.2 数据库与 RLS 策略错误问题前端应用无法插入数据到 Supabase 表报错“new row violates row-level security policy”。排查步骤 1确认你尝试操作的表已启用 RLS表编辑页面顶部开关为绿色。排查步骤 2检查你使用的 Supabase 客户端实例的密钥。前端操作必须使用anon key即NEXT_PUBLIC_SUPABASE_ANON_KEY并且受到 RLS 策略限制。排查步骤 3仔细检查 INSERT 策略的WITH CHECK条件。例如对于articles表策略auth.uid() user_id要求插入的数据行中user_id字段的值必须等于当前登录用户的 ID。这意味着你在前端执行insert时必须显式地在数据中包含user_id字段并且其值要从supabase.auth.getUser()中获取。一个常见的错误是忘记传这个字段。// 正确的插入示例 const { data: userData } await supabase.auth.getUser() const { error } await supabase .from(articles) .insert({ title: My Article, content: ..., user_id: userData.user?.id // 关键必须提供当前用户的ID })问题使用服务角色密钥的服务器端操作也报 RLS 错误。排查步骤服务角色密钥 (SUPABASE_SERVICE_ROLE_KEY) 创建的客户端默认会绕过所有 RLS 策略。如果仍然遇到权限错误请检查连接是否真的使用了服务角色密钥。确保服务器端环境变量SUPABASE_SERVICE_ROLE_KEY已正确设置并且你调用的是createServerSupabaseClient()或使用服务角色密钥初始化的客户端。9.3 邮件发送失败问题Supabase 密码重置邮件发送失败但在 Resend 仪表板看不到发送记录。排查步骤 1在 Supabase 项目的Authentication - Providers - Email设置中确认“Confirm email”和“Recover password”等功能是启用的。排查步骤 2在 SupabaseProject Settings - Authentication - SMTP Settings中确认Enable Custom SMTP已打开并且所有配置尤其是Sender email和Password/API Key正确无误。可以再次点击“Send test email”。排查步骤 3检查 Resend 中配置的Sender email地址的域名是否已经完成了 DNS 验证在 Resend Domains 页面显示为 “Verified”。未验证的域名无法发送邮件。排查步骤 4查看 Supabase 项目的Logs在左侧边栏底部过滤auth相关的日志看是否有更详细的错误信息。9.4 环境变量与构建问题问题本地开发正常但部署到 Vercel 等平台后应用无法连接 Supabase。排查步骤这是最经典的部署问题。确保你在 Vercel 项目的Environment Variables设置中添加了所有必要的环境变量NEXT_PUBLIC_SUPABASE_URL,NEXT_PUBLIC_SUPABASE_ANON_KEY,SUPABASE_SERVICE_ROLE_KEY。并且注意修改环境变量后需要重新部署项目才能生效。问题TypeScript 报错找不到/components/ui下的模块。排查步骤检查tsconfig.json文件中的baseUrl和paths配置。使用/*别名通常需要如下配置{ compilerOptions: { baseUrl: ., paths: { /*: [./*] } } }另外确保你已经运行了npx shadcnlatest add命令组件确实被添加到了components/ui目录下。有时 CLI 可能会因为网络问题添加失败。这套从零开始搭建的现代全栈开发环境融合了当前最主流和高效的工具。从 UI 到数据库从认证到邮件每个环节都选择了在开发者体验和产品能力上表现优异的服务。整个配置过程虽然涉及多个平台但一旦打通后续的功能迭代速度会非常快。最大的体会是清晰的环境隔离和安全意识如 RLS、密钥管理必须从项目第一天就开始建立这比事后补救要轻松得多。利用好 Cursor 这样的 AI 工具可以把更多精力集中在业务逻辑和创新上而不是繁琐的配置语法。
返回列表