集成

构建Supabase集成

本指南将逐步介绍如何使用OAuth2和管理API构建Supabase集成,使您能够代表用户管理其组织和项目。


通过OAuth2.0协议,您可以获取访问令牌和刷新令牌,使您的应用能够代表用户完全访问管理API

创建OAuth应用

  1. 在您组织的设置中,导航至OAuth应用标签页
  2. 在页面右上角区域,点击添加应用
  3. 填写必填信息后点击确认

显示"连接Supabase"按钮

在您的用户界面中添加"连接Supabase"按钮来启动OAuth流程。请遵循我们品牌素材中列出的设计规范。

实现OAuth 2.0流程

在Supabase上发布OAuth应用后,您可以使用OAuth 2.0协议获取Supabase用户的授权来管理他们的组织和项目。

您可以使用偏好的OAuth2客户端,或按照以下步骤操作。我们GitHub上提供了TypeScript示例实现,该示例使用Supabase边缘函数。

重定向到授权 URL

在您的应用界面中,将用户重定向至 https://api.supabase.com/v1/oauth/authorize。请确保包含所有必需的查询参数,例如:

  • client_id:来自上述应用创建步骤的客户端ID
  • redirect_uri:用户授权后Supabase将重定向到的URL
  • response_type:设置为code
  • state:关于应用状态的信息。注意redirect_uristate的总大小不能超过4kB
  • (推荐)PKCE:强烈建议使用PKCE流程增强安全性。在将用户引导至授权端点前生成随机值(称为code verifier),使用SHA256哈希后作为code_challenge参数传递,同时将code_challenge_method设为S256。在下一步中,您需要提供该code verifier来获取首个访问令牌和刷新令牌
  • [已弃用] scope:作用域在创建OAuth应用时配置。详见文档
1
2
3
4
5
6
7
8
9
10
11
12
router.get('/connect-supabase/login', async (ctx) => { // 构建授权重定向URL并获取PKCE codeVerifier const { uri, codeVerifier } = await oauth2Client.code.getAuthorizationUri() console.log(uri.toString()) // 控制台输出: https://api.supabase.com/v1/oauth/authorize?response_type=code&client_id=7673bde9-be72-4d75-bd5e-b0dba2c49b38&redirect_uri=http%3A%2F%2Flocalhost%3A54321%2Ffunctions%2Fv1%2Fconnect-supabase%2Foauth2%2Fcallback&scope=all&code_challenge=jk06R69S1bH9dD4td8mS5kAEFmEbMP5P0YrmGNAUVE0&code_challenge_method=S256 // 将codeVerifier存储在用户会话(cookie)中 ctx.state.session.flash('codeVerifier', codeVerifier) // 将用户重定向至授权端点 ctx.response.redirect(uri)})

完整示例请参见GitHub

处理回调

当用户同意为您的OAuth应用提供API访问权限后,Supabase会将用户重定向到上一步提供的redirect_uri。该URL将包含以下查询参数:

  • code:授权码,您需要与Supabase交换以获取访问令牌和刷新令牌
  • state:上一步中您提供的值,用于帮助您将请求与用户关联。此处返回的state属性应与您之前发送的state进行比较

通过调用POST https://api.supabase.com/v1/oauth/token来交换授权码获取访问令牌和刷新令牌,使用以下查询参数作为application/x-www-form-urlencoded内容类型:

  • grant_type:值为authorization_code
  • code:上一步返回的code
  • redirect_uri:必须与第一步使用的URL完全相同
  • (推荐)code_verifier:如果在第一步使用了PKCE流程,请包含代码验证器作为code_verifier

根据OAuth2规范,通过基本认证头提供客户端ID和客户端密钥:

  • client_id:标识您OAuth应用的唯一客户端ID
  • client_secret:向Supabase认证您OAuth应用的密钥
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
router.get('/connect-supabase/oauth2/callback', async (ctx) => { // 确保用户会话中存在codeVerifier const codeVerifier = ctx.state.session.get('codeVerifier') as string if (!codeVerifier) throw new Error('No codeVerifier!') // 将授权码交换为访问令牌 const tokens = await fetch(config.tokenUri, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', Accept: 'application/json', Authorization: `Basic ${btoa(`${config.clientId}:${config.clientSecret}`)}`, }, body: new URLSearchParams({ grant_type: 'authorization_code', code: ctx.request.url.searchParams.get('code') || '', redirect_uri: config.redirectUri, code_verifier: codeVerifier, }), }).then((res) => res.json()) console.log('tokens', tokens) // 将令牌存储在数据库中供后续使用 ctx.response.body = 'Success'})

完整示例可在GitHub上查看。

刷新访问令牌

您可以使用 POST /v1/oauth/token 端点,通过上一节返回的刷新令牌来刷新访问令牌。

如果用户已撤销对您应用的访问权限,您将无法刷新令牌。此外,访问令牌也将失效。在调用任何 Supabase API 时,请确保处理好 HTTP 未授权错误。

调用管理 API

有关管理 API 的认证详情,请参考管理 API 参考文档

使用 JavaScript (TypeScript) SDK

为方便起见,在使用 JavaScript/TypeScript 时,您可以使用 supabase-management-js 库。

1
2
3
import { SupabaseManagementAPI } from 'supabase-management-js'const client = new SupabaseManagementAPI({ accessToken: '<access token>' })

集成建议

您可以考虑在集成中添加以下几种常见模式,以提升用户体验。

将 API 密钥存储在环境变量中

某些集成(例如 Cloudflare Workers)提供了便捷的 API URL 和 API 密钥访问方式,可加速开发流程。

通过管理 API,您可以使用 /projects/{ref}/api-keys 端点 获取项目的 API 凭证。

预填数据库连接信息

如果您的集成需要直接连接项目数据库,可以预先为用户填充Postgres连接信息,遵循以下格式:

1
postgresql://postgres:[DB-PASSWORD]@db.[REF].supabase.co:5432/postgres

请注意,您无法通过管理API获取数据库密码,因此对于用户现有项目,您需要在界面中收集他们的数据库密码。

创建新项目

使用/v1/projects端点创建新项目。

创建新项目时,您可以要求用户提供数据库密码,也可以为他们生成安全密码。无论哪种方式,请确保在您这边安全存储数据库密码,以便构建Postgres连接URI。

配置自定义Auth SMTP

您可以使用/config/auth端点配置用户的自定义SMTP设置

处理动态重定向URL

要在同一个OAuth应用中处理多个动态生成的重定向URL,可以利用state查询参数。在启动OAuth流程时,将期望的编码后重定向URL包含在state参数中。授权完成后,我们会将state值返回给您的应用。您可以验证其完整性并提取正确的重定向URL,解码后将用户重定向到正确的URL。

当前限制

在我们推出细粒度访问控制之前,只有部分功能可用。如果您需要完整的数据库访问权限,则需要提示用户输入其数据库密码。