更新时间:2026-10-21 GMT+08:00
分享

用户认证(Authentication)

场景介绍

任何面向最终用户的商用应用或服务,都绕不开“谁在用我的应用”这一问题:要区分用户身份、归属数据、控制可见内容、记录操作来源。用户认证(Authentication)正是解决此问题的模块,负责注册、登录、会话维持与注销,为每位用户分配唯一身份并在后续请求中持续验证。如同门禁先识别访客才放行,应用也须先识别用户,才能放行后续操作。

传统做法通常需要客户自行研发,包括建立用户表、编写密码加密与校验逻辑、实现令牌签发与会话刷新功能、找回密码机制以及第三方对接等,同时还需兼顾防撞库、防重放、防注入与安全合规要求,导致研发与运维成本较高。

华为云RDS Supabase的认证模块开箱即用,其核心作用是帮助开发者快速、安全地完成用户注册、登录及权限控制,无需从零构建复杂的安全底座,可显著缩短研发周期;密码哈希、会话安全、防暴力破解等安全机制均由平台托管,符合现代网络安全标准,有效降低自建账号系统漏洞导致的数据泄露风险。

模块提供邮箱密码与GitHub单点登录(SSO)两种方式,覆盖常见登录场景;自动处理访问令牌(Access Token)与刷新令牌(Refresh Token)的生成、分发与刷新,维持安全的登录状态;并与行级安全(RLS)深度整合。登录后自动获得authenticated身份,可按当前登录用户UID在数据库层面限制数据读写,未登录仅持anon低权限(实际行级隔离需配合RLS策略配置,详见数据库API(Database Data API))。模块独立可用,可灵活接入您的应用。本章介绍认证方式、Auth配置及SDK操作。

认证方式

华为云RDS Supabase支持以下两种认证方式,详见表1。

表1 认证方式概览

认证方式

适用场景

邮箱认证(SMTP)

用户使用邮箱 + 密码注册与登录,系统通过SMTP发送确认邮件完成验证。适用于需要自主管理用户账号体系、面向通用用户的场景。

GitHub OAuth

用户使用GitHub账号进行第三方单点登录(SSO),无需在应用内另行注册。适用于面向开发者、技术团队,或希望借助GitHub既有账号体系快速登录的场景。

华为云RDS Supabase不支持手机号/SMS、微信、支付宝、Google账号登录;GitHub是唯一支持的第三方OAuth登录方式。

认证状态与RLS角色

认证模块与行级安全(RLS)联动,登录状态决定访问数据时所用的数据库角色,进而决定可见数据范围。

表2 认证状态与RLS角色

认证状态

RLS角色

说明

未登录 + Publishable Key

anon

匿名用户,仅受anon策略约束。

已登录 + Publishable Key

authenticated

认证用户,受authenticated策略约束。

Secret Key / Service Role Key

Bypass RLS

服务端高权限,绕过行级安全。

实际行级隔离需配合RLS策略配置,详见数据库API(Database Data API)。

Auth配置

Auth配置是控制台集中管理认证能力的入口,可在此完成认证方式的启停与参数调配:启用并配置邮箱认证、GitHub第三方登录,控制用户注册与匿名访问,设置各类邮件模板等。

Auth配置入口:单击Supabase应用名称,进入应用详情页,即可看到Auth配置入口,详细操作见用户认证Auth配置管理。

表3 Auth配置类别

配置类别

说明

邮箱IDP(SMTP)

SMTP主机、端口、用户名、密码(授权码)、管理员邮箱、发件人姓名、邮箱自动确认、发件速率限制等,详见配置IDP身份验证提供商(邮箱)。

GitHub IDP

GitHub OAuth App的Client ID、Client Secret、回调URL,详见配置IDP身份验证提供商(GitHub)。

访问控制

站点URL、允许重定向的URL列表、是否允许新用户注册、是否允许匿名用户,详见访问控制。

邮件模板

涵盖邮箱确认、邀请、密码重置、邮箱变更、魔法链接、重新认证等场景,模板可用Storage Bucket托管,详见配置邮箱模板。

邮件模板中的魔法链接对应无密码邮箱登录(通过signInWithOtp发送一次性登录链接)。华为云RDS Supabase当前主推邮箱密码认证,魔法链接模板为预置项,供按需扩展使用,本文不展开介绍。

邮箱认证(SMTP)

SMTP(简单邮件传输协议)是发送邮件的标准协议,邮箱认证即依赖SMTP服务器发送确认与通知邮件。通过邮箱认证形成完整闭环:注册 → 登录 → 认证状态 → 更新用户(邮箱与密码) → 注销

邮箱认证围绕邮箱+密码与邮件验证构建,支持的核心业务场景与功能如下:

  • 注册与登录:用户以邮箱+密码注册、登录。
  • 邮箱确认:注册后发送确认邮件验证邮箱归属,防止伪造账号。
  • 魔法链接登录:无密码场景,发送一次性登录链接,点击即登录。
  • 密码重置:忘记密码时,通过邮箱重置链接恢复访问。
  • 邮箱变更:换绑邮箱时,向新邮箱发确认链接,确认后生效。
  • 信息与会话维护:更新邮箱/密码、监听登录状态、注销。

各流程邮件均经SMTP发送,模板可在控制台Auth配置中定制。

  • 邮箱注册
    const { data, error } = await supabase.auth.signUp({
      email: 'user@example.com', // 邮箱地址
      password: 'your-password', // 邮箱密码
    })

    调用后系统创建用户并发送确认邮件。若控制台开启了“邮箱自动确认”,邮箱即时验证通过,用户注册后即处于登录态;否则需点击确认邮件中的链接完成验证,方可登录获取会话。

    前提: 未开启“邮箱自动确认”时,注册依赖已配置且可达的SMTP服务发送确认邮件;若SMTP未配置或不可达,用户将无法收到确认邮件、无法完成注册。

  • 邮箱登录
    const { data, error } = await supabase.auth.signInWithPassword({
      email: 'user@example.com',  // 邮箱地址
      password: 'your-password',  // 邮箱密码
    })

    调用返回{ data, error }:成功时error为null、data含登录会话;失败时(如密码错误、用户不存在)error非空,根据该错误,判断并提示用户。

    if (error) {
      console.error('登录失败:', error.message)
      return
    }
  • 监听认证状态

    会话(session)是用户登录后的凭证,登录凭证(JWT)具备有效期;SDK会在凭证过期前自动续期、无需手动处理,TOKEN_REFRESHED事件在凭证续期时触发。

    可监听认证状态变化以联动界面。

    supabase.auth.onAuthStateChange((event, session) => {
      console.log('认证事件:', event)
      console.log('当前会话:', session)
    })
    表4 邮箱认证状态事件

    事件

    说明

    INITIAL_SESSION

    客户端初始化时触发,用于恢复已有会话。

    SIGNED_IN

    用户登录。

    SIGNED_OUT

    用户注销。

    TOKEN_REFRESHED

    登录凭证自动续期。

    PASSWORD_RECOVERY

    密码恢复流程触发(用户请求重置密码时)。

    USER_UPDATED

    用户信息更新。

  • 邮箱变更
    const { data, error } = await supabase.auth.updateUser({ email: 'new-email@example.com' })
    if (error) {
      console.error('邮箱变更失败:', error.message)
      return
    }

    用户必须处于登录状态才能调用updateUser()。调用后系统向新邮箱发送“邮箱变更”确认邮件,用户须点击确认链接后新邮箱才正式生效;未确认前旧邮箱仍可用于登录。

  • 密码重置
    用户忘记密码时,可通过邮箱重置:先发送重置邮件,用户点击邮件中的重置链接回到应用后,再设置新密码。
    // 发送密码重置邮件
    const { data, error } = await supabase.auth.resetPasswordForEmail(
      'user@example.com',    // 邮箱地址
      { emailRedirectTo: 'https://your-app.com/reset-password' }
    )
    if (error) {
      console.error('发送重置邮件失败:', error.message)
      return
    }

    用户点击重置链接后,被重定向回应用并触发PASSWORD_RECOVERY事件,此时处于密码重置状态,可在重置页面调用updateUser设置新密码。

    // 用户输入新密码后重置
    const { data, error } = await supabase.auth.updateUser({ password: 'new-password' })
    if (error) {
      console.error('重置密码失败:', error.message)
      return
    }

    重置链接一次性有效;需在控制台Auth配置中启用邮箱认证并使用“密码恢复”邮件模板。密码可能因强度不足等被拒绝,请判断error并提示用户。

  • 用户注销
    // 默认登出当前用户在所有设备的会话
    const { error } = await supabase.auth.signOut()
    
    // 如仅登出当前会话(保留其他设备登录),显式指定 local
    const { error } = await supabase.auth.signOut({ scope: 'local' })

    signOut()默认scope为global,会登出该用户在所有设备的会话;若只想退出当前会话,须显式传{ scope: 'local' }。两种方式均会触发SIGNED_OUT事件。

  • 魔法链接(无密码登录)
    魔法链接(Magic Link)是一种无密码邮箱登录方式:用户输入邮箱,系统发送一封含一次性登录链接的邮件,用户点击链接即完成登录,无需记忆密码。适用于希望降低注册门槛、减少密码运维的场景。
    // 发送魔法链接邮件
    const { data, error } = await supabase.auth.signInWithOtp({
      email: 'user@example.com',    // 邮箱地址
      options: {
        emailRedirectTo: 'https://your-app.com/dashboard'
      }
    })
    if (error) {
      console.error('发送登录链接失败:', error.message)
      return
    }

    用户收到邮件后点击链接,即被重定向回应用并完成登录,随后触发SIGNED_IN事件;魔法链接一次性有效,登录后即失效。魔法链接依赖已配置且可达的SMTP服务,并使用控制台Auth配置中的“魔法链接”邮件模板。

GitHub OAuth(SSO单点登录)

OAuth是一种开放授权标准,允许用户使用已有的第三方账号登录应用,而无需在应用内另行设置密码。GitHub OAuth即通过GitHub账号实现第三方登录(常被类比为单点登录):用户无需在应用内另行注册账号或设置密码,只需使用已有的GitHub账号授权一次即可登录应用,以GitHub作为可信身份来源。通过GitHub OAuth形成完整闭环:登录 → 认证状态 → 更新用户(邮箱与密码) → 注销

  • GitHub登录
    调用后,SDK在浏览器端自动重定向至GitHub完成身份认证与授权;用户在GitHub确认后,GitHub回调携带授权码,应用据此换取会话,用户即处于登录态。整个登录过程由GitHub侧保管凭证,应用不接触用户密码。
    // 基本调用
    const { data, error } = await supabase.auth.signInWithOAuth({ provider: 'github' })
    
    // 指定回调后重定向地址
    const { data, error } = await supabase.auth.signInWithOAuth({
      provider: 'github',
      options: { redirectTo: 'https://your-app.com/dashboard' }
    })

    回调地址分两层:

    • GitHub OAuth App的Authorization callback URL:GitHub完成认证后携带授权码回传至Supabase的地址。
    • redirectTo:Supabase处理完授权码后跳转回应用的业务页面地址(如上方示例)。
  • 监听认证状态
    supabase.auth.onAuthStateChange((event, session) => {
      console.log('认证事件:', event)
      console.log('当前会话:', session)
    })

    监听方式与事件清单与邮箱认证完全一致,详见表4。

  • 邮箱变更
    const { data, error } = await supabase.auth.updateUser({ email: 'new-email@example.com' })
    if (error) {
      console.error('邮箱变更失败:', error.message)
      return
    }

    用户必须处于登录状态才能调用updateUser()。调用后系统向新邮箱发送“邮箱变更”确认邮件,用户须点击确认链接后新邮箱才正式生效。用法与邮箱认证一致。

  • 密码重置
    // 发送密码重置邮件
    const { data, error } = await supabase.auth.resetPasswordForEmail(
      'user@example.com',    // 邮箱地址
      { emailRedirectTo: 'https://your-app.com/reset-password' }
    )
    if (error) {
      console.error('发送重置邮件失败:', error.message)
      return
    }

    用户点击重置链接后触发PASSWORD_RECOVERY事件,在重置页面调用updateUser设置新密码。通过GitHub SSO登录的用户在应用内没有密码,密码重置项可用于为其设置应用内密码;若始终仅用GitHub登录,可跳过密码重置。

  • 用户注销
    const { error } = await supabase.auth.signOut() 

    signOut()默认scope为global,会登出该用户在所有设备的会话;若只想退出当前会话,须显式传{ scope: 'local' }。

相关文档