docs: Add OAuth App Authorization Flow example (#29508)

This commit is contained in:
Kamil Ogórek
2024-09-27 19:12:09 +02:00
committed by GitHub
parent b5eadc1455
commit a0ce795bdf
6 changed files with 91 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
SUPABASE_REDIRECT_URL=http://localhost:3000/callback
SUPABASE_CLIENT_ID=
SUPABASE_CLIENT_SECRET=

View File

@@ -0,0 +1,4 @@
node_modules/
bun.lockb
package-lock.json
.env

View File

@@ -0,0 +1,8 @@
# Supabase OAuth Apps Login Flow
1. Create OAuth App at https://supabase.com/dashboard/org/_/apps
2. Use http://localhost:3000 as `Authorization callback URLs`
3. Copy `.env.example` to `.env` and fill `Client ID` and `Client Secret` with values from newly created app
4. `bun install`
5. `bun run dev`
6. Open http://localhost:3000

View File

@@ -0,0 +1,12 @@
{
"name": "supabase-oauth-example",
"scripts": {
"dev": "bun run --hot src/index.ts"
},
"dependencies": {
"hono": "^4.6.3"
},
"devDependencies": {
"@types/bun": "latest"
}
}

View File

@@ -0,0 +1,59 @@
import { env } from 'bun'
import { Hono } from 'hono'
declare module 'bun' {
interface Env {
SUPABASE_REDIRECT_URL: string
SUPABASE_CLIENT_ID: string
SUPABASE_CLIENT_SECRET: string
}
}
const AUTHORIZATION_URL = 'https://api.supabase.com/v1/oauth/authorize'
const TOKEN_URL = 'https://api.supabase.com/v1/oauth/token'
const app = new Hono()
app.get('/', (c) => {
const params = new URLSearchParams({
client_id: env.SUPABASE_CLIENT_ID,
redirect_uri: env.SUPABASE_REDIRECT_URL,
response_type: 'code',
})
return c.html(`
<!doctype>
<html>
<body>
<a href="${AUTHORIZATION_URL}?${params.toString()}"><button>Login with Supabase</button></a>
</body>
</html>
`)
})
app.get('/callback', async (c) => {
const tokensResponse = await fetch(TOKEN_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json',
Authorization: `Basic ${btoa(`${env.SUPABASE_CLIENT_ID}:${env.SUPABASE_CLIENT_SECRET}`)}`,
},
body: new URLSearchParams({
grant_type: 'authorization_code',
code: c.req.query('code') ?? '',
redirect_uri: env.SUPABASE_REDIRECT_URL,
}),
})
const tokens = (await tokensResponse.json()) as {
access_token: string
refresh_token: string
expires_in: number
token_type: 'Bearer'
}
return c.text(JSON.stringify(tokens, null, 2))
})
export default app

View File

@@ -0,0 +1,5 @@
{
"compilerOptions": {
"strict": true
}
}