Supabase 完整流程:设置 GitHub OAuth 登录

45 min read

概述

要为您的应用程序启用 GitHub 登录,您需要完成以下三个部分:

  1. 在 GitHub 上创建并配置 OAuth 应用
  2. 将 GitHub OAuth 密钥添加到 Supabase 项目
  3. 在 Supabase JS 客户端应用中添加登录代码

1. 获取回调 URL

回调 URL 的格式如下:

https://<project-ref>.supabase.co/auth/v1/callback

步骤:

  1. 进入您的 Supabase 项目仪表板。
  2. 点击左侧边栏中的 Authentication(认证) 图标。
  3. Configuration(配置) 部分下,点击 Providers(提供者)
  4. 点击 GitHub,展开后您将看到回调 URL。点击 Copy 复制到剪贴板。

提示: 如果使用 Supabase CLI 在本地进行 OAuth 测试,请参阅本地开发文档。


2. 在 GitHub 上注册新的 OAuth 应用

步骤:

  1. 导航到 GitHub OAuth 应用页面.
  2. 点击 Register a new application。如果之前创建过应用,点击 New OAuth App
  3. 填写以下信息:
    • Application name(应用名称): 输入您的应用名称。
    • Homepage URL(主页 URL): 输入您的应用网站的完整 URL。
    • Authorization callback URL(授权回调 URL): 输入前面获取的回调 URL。
  4. 保持 Enable Device Flow 未选中。
  5. 点击 Register Application 注册应用。
  6. 复制并保存 Client ID
  7. 点击 Generate a new client secret 生成新的客户端密钥,并复制保存 Client Secret

3. 将 GitHub 凭证添加到 Supabase 项目

步骤:

  1. 返回 Supabase 项目仪表板。
  2. 在左侧边栏中,点击 Authentication(认证) 图标。
  3. Configuration(配置) 部分下,点击 Providers(提供者)
  4. 点击 GitHub,展开后将 GitHub Enabled 开关打开。
  5. 输入之前复制的 GitHub Client IDGitHub Client Secret
  6. 点击 Save 保存配置。

4. 在客户端应用中添加登录代码

根据您使用的技术栈,选择相应的代码示例进行集成。

JavaScript 示例:

async function signInWithGithub() {
  const { data, error } = await supabase.auth.signInWithOAuth({
    provider: 'github',
  });
}

注意:

  • 如果不使用服务器端渲染(SSR)或基于 Cookie 的认证,可以直接使用 @supabase/supabase-js 中的 createClient
  • 如果使用 SSR,请参阅服务器端认证指南以了解如何创建 Supabase 客户端。

处理回调(以 Next.js 为例):
创建一个新的文件 app/auth/callback/route.ts,并添加以下内容:

import { NextResponse } from 'next/server'
import { createClient } from '@/utils/supabase/server'

export async function GET(request: Request) {
  const { searchParams, origin } = new URL(request.url)
  const code = searchParams.get('code')
  const next = searchParams.get('next') ?? '/'

  if (code) {
    const supabase = createClient()
    const { error } = await supabase.auth.exchangeCodeForSession(code)
    if (!error) {
      const forwardedHost = request.headers.get('x-forwarded-host')
      const isLocalEnv = process.env.NODE_ENV === 'development'
      if (isLocalEnv) {
        return NextResponse.redirect(`${origin}${next}`)
      } else if (forwardedHost) {
        return NextResponse.redirect(`https://${forwardedHost}${next}`)
      } else {
        return NextResponse.redirect(`${origin}${next}`)
      }
    }
  }

  return NextResponse.redirect(`${origin}/auth/auth-code-error`)
}

5. 用户登出

当用户登出时,调用 signOut() 方法以移除浏览器会话和 localStorage 中的任何对象。

示例:

async function signOut() {
  const { error } = await supabase.auth.signOut()
}