🎯

bknd-oauth-setup

🎯Skill

from cameronapak/bknd-skills

VibeIndex|
What it does

Configures OAuth authentication providers like Google and GitHub in a Bknd application, handling credentials, callback URLs, and strategy setup.

πŸ“¦

Part of

cameronapak/bknd-skills(55 items)

bknd-oauth-setup

Installation

Quick InstallInstall with npx
npx add-skill cameronapak/bknd-skills
Quick InstallInstall with npx
npx add-skill cameronapak/bknd-skills -a cursor -a claude-code
Quick InstallInstall with npx
npx add-skill cameronapak/bknd-skills -g
πŸ“– Extracted from docs: cameronapak/bknd-skills
4Installs
-
AddedFeb 4, 2026

Skill Details

SKILL.md

Use when configuring OAuth or social login providers in a Bknd application. Covers Google OAuth, GitHub OAuth, custom OAuth providers, callback URLs, environment variables, and frontend OAuth integration.

Overview

# OAuth/Social Login Setup

Configure OAuth authentication providers (Google, GitHub, or custom) in Bknd.

Prerequisites

  • Bknd project with auth enabled (bknd-setup-auth)
  • OAuth app credentials from provider (client_id, client_secret)
  • For Google: Google Cloud Console project with OAuth 2.0 credentials
  • For GitHub: GitHub OAuth App in Developer Settings
  • For custom: Provider's authorization server endpoints

When to Use UI Mode

  • Testing OAuth login flow via admin panel
  • Viewing enabled OAuth strategies
  • Checking callback URL configuration

UI steps: Admin Panel > Auth > Strategies

When to Use Code Mode

  • Configuring OAuth providers in bknd.config.ts
  • Setting up multiple OAuth providers
  • Implementing frontend OAuth buttons
  • Configuring custom OAuth providers (Slack, Discord, etc.)

Built-in OAuth Providers

Bknd has pre-configured support for:

| Provider | Type | Scopes |

|----------|------|--------|

| google | OIDC | openid, email, profile |

| github | OAuth2 | read:user, user:email |

Google OAuth Setup

1. Create Google OAuth Credentials

  1. Go to [Google Cloud Console](https://console.cloud.google.com/)
  2. Create project or select existing
  3. Navigate: APIs & Services > Credentials
  4. Click Create Credentials > OAuth client ID
  5. Application type: Web application
  6. Add authorized redirect URI:

```

http://localhost:7654/api/auth/google/callback

```

(Replace with your production URL)

  1. Copy Client ID and Client Secret

2. Configure Bknd

```typescript

// bknd.config.ts

import { defineConfig } from "bknd";

export default defineConfig({

auth: {

enabled: true,

jwt: {

secret: process.env.JWT_SECRET!,

expires: 604800,

},

strategies: {

google: {

type: "oauth",

enabled: true,

config: {

name: "google",

client: {

client_id: process.env.GOOGLE_CLIENT_ID!,

client_secret: process.env.GOOGLE_CLIENT_SECRET!,

},

},

},

},

},

});

```

3. Environment Variables

```bash

# .env

GOOGLE_CLIENT_ID=your-google-client-id.apps.googleusercontent.com

GOOGLE_CLIENT_SECRET=your-google-client-secret

JWT_SECRET=your-256-bit-secret

```

GitHub OAuth Setup

1. Create GitHub OAuth App

  1. Go to [GitHub Developer Settings](https://github.com/settings/developers)
  2. Click New OAuth App
  3. Fill in:

- Application name: Your app name

- Homepage URL: http://localhost:7654

- Authorization callback URL: http://localhost:7654/api/auth/github/callback

  1. Click Register application
  2. Copy Client ID and generate Client Secret

2. Configure Bknd

```typescript

// bknd.config.ts

import { defineConfig } from "bknd";

export default defineConfig({

auth: {

enabled: true,

jwt: {

secret: process.env.JWT_SECRET!,

expires: 604800,

},

strategies: {

github: {

type: "oauth",

enabled: true,

config: {

name: "github",

client: {

client_id: process.env.GITHUB_CLIENT_ID!,

client_secret: process.env.GITHUB_CLIENT_SECRET!,

},

},

},

},

},

});

```

3. Environment Variables

```bash

# .env

GITHUB_CLIENT_ID=your-github-client-id

GITHUB_CLIENT_SECRET=your-github-client-secret

JWT_SECRET=your-256-bit-secret

```

Multiple OAuth Providers

Enable multiple providers simultaneously:

```typescript

// bknd.config.ts

import { defineConfig } from "bknd";

export default defineConfig({

auth: {

enabled: true,

jwt: {

secret: process.env.JWT_SECRET!,

expires: 604800,

},

strategies: {

password: {

type: "password",

enabled: true,

config: {

hashing: "bcrypt",

rounds: 4,

},

},

google: {

type: "oauth",

enabled: true,

config: {

name: "google",

client: {

client_id: process.env.GOOGLE_CLIENT_ID!,

client_secret: process.env.GOOGLE_CLIENT_SECRET!,

},

},

},

github: {

type: "oauth",

enabled: true,

config: {

name: "github",

client: {

client_id: process.env.GITHUB_CLIENT_ID!,

client_secret: process.env.GITHUB_CLIENT_SECRET!,

},

},

},

},

},

});

```

Custom OAuth Provider

For providers not built-in (Slack, Discord, Microsoft, etc.):

```typescript

// bknd.config.ts

import { defineConfig } from "bknd";

export default defineConfig({

auth: {

enabled: true,

strategies: {

slack: {

type: "custom_oauth",

enabled: true,

config: {

name: "slack",

type: "oauth2", // "oauth2" or "oidc"

client: {

client_id: process.env.SLACK_CLIENT_ID!,

client_secret: process.env.SLACK_CLIENT_SECRET!,

token_endpoint_auth_method: "client_secret_basic",

},

as: {

issuer: "https://slack.com",

authorization_endpoint: "https://slack.com/oauth/v2/authorize",

token_endpoint: "https://slack.com/api/oauth.v2.access",

userinfo_endpoint: "https://slack.com/api/users.identity",

scopes_supported: ["openid", "profile", "email"],

},

},

},

},

},

});

```

Custom OAuth config options:

| Property | Type | Required | Description |

|----------|------|----------|-------------|

| name | string | Yes | Strategy identifier |

| type | "oauth2" \| "oidc" | Yes | Protocol type |

| client.client_id | string | Yes | OAuth client ID |

| client.client_secret | string | Yes | OAuth client secret |

| client.token_endpoint_auth_method | string | Yes | Auth method (client_secret_basic) |

| as.issuer | string | Yes | Authorization server issuer URL |

| as.authorization_endpoint | string | Yes | OAuth authorize URL |

| as.token_endpoint | string | Yes | Token exchange URL |

| as.userinfo_endpoint | string | No | User info URL |

| as.scopes_supported | string[] | No | Available scopes |

OAuth Endpoints

Once configured, Bknd exposes these endpoints:

| Method | Path | Description |

|--------|------|-------------|

| POST | /api/auth/{provider}/login | Start OAuth login (cookie mode) |

| POST | /api/auth/{provider}/register | Start OAuth registration (cookie mode) |

| GET | /api/auth/{provider}/login | Get OAuth URL (token mode) |

| GET | /api/auth/{provider}/callback | OAuth callback handler |

Frontend Integration

Cookie-Based Flow (Recommended for SSR)

```typescript

// Redirect user to OAuth provider

function loginWithGoogle() {

// POST redirects to Google, callback sets cookie, redirects to pathSuccess

const form = document.createElement("form");

form.method = "POST";

form.action = "http://localhost:7654/api/auth/google/login";

document.body.appendChild(form);

form.submit();

}

```

Token-Based Flow (SPA)

```typescript

import { Api } from "bknd";

const api = new Api({

host: "http://localhost:7654",

storage: localStorage,

});

async function loginWithGoogle() {

// Get OAuth URL

const { data } = await api.auth.login("google");

if (data?.url) {

// Store challenge for callback verification

sessionStorage.setItem("oauth_challenge", data.challenge);

// Redirect to Google

window.location.href = data.url;

}

}

// On callback page, complete the flow

async function handleOAuthCallback() {

const params = new URLSearchParams(window.location.search);

const code = params.get("code");

const challenge = sessionStorage.getItem("oauth_challenge");

if (code && challenge) {

// Complete OAuth flow

const response = await fetch(

http://localhost:7654/api/auth/google/callback?code=${code},

{

headers: {

"X-State-Challenge": challenge,

"X-State-Action": "login",

},

}

);

const { user, token } = await response.json();

api.setToken(token);

sessionStorage.removeItem("oauth_challenge");

}

}

```

React OAuth Buttons

```tsx

import { useAuth } from "@bknd/react";

function OAuthButtons() {

const { login } = useAuth();

async function handleGoogleLogin() {

const result = await login("google");

if (result.data?.url) {

window.location.href = result.data.url;

}

}

async function handleGitHubLogin() {

const result = await login("github");

if (result.data?.url) {

window.location.href = result.data.url;

}

}

return (

);

}

```

OAuth Callback Page (React)

```tsx

import { useEffect, useState } from "react";

import { useNavigate } from "react-router-dom";

import { Api } from "bknd";

const api = new Api({

host: import.meta.env.VITE_API_URL,

storage: localStorage,

});

function OAuthCallback() {

const navigate = useNavigate();

const [error, setError] = useState(null);

useEffect(() => {

const params = new URLSearchParams(window.location.search);

const code = params.get("code");

const challenge = sessionStorage.getItem("oauth_challenge");

if (!code) {

setError("No authorization code received");

return;

}

if (!challenge) {

setError("OAuth session expired. Please try again.");

return;

}

fetch(${import.meta.env.VITE_API_URL}/api/auth/google/callback?code=${code}, {

headers: {

"X-State-Challenge": challenge,

"X-State-Action": "login",

},

})

.then((res) => res.json())

.then(({ user, token }) => {

api.setToken(token);

sessionStorage.removeItem("oauth_challenge");

navigate("/dashboard");

})

.catch((err) => {

setError("Authentication failed. Please try again.");

});

}, [navigate]);

if (error) {

return (

{error}

Back to login

);

}

return

Completing sign in...
;

}

```

Callback URL Configuration

Development:

```

http://localhost:7654/api/auth/{provider}/callback

```

Production:

```

https://api.yourapp.com/api/auth/{provider}/callback

```

Update redirect URIs in provider dashboard when deploying.

Cookie Settings for OAuth

Configure cookie behavior for OAuth flow:

```typescript

{

auth: {

cookie: {

secure: process.env.NODE_ENV === "production", // HTTPS only in prod

httpOnly: true,

sameSite: "lax", // Required for OAuth redirects

pathSuccess: "/dashboard", // Redirect after login

pathLoggedOut: "/login", // Redirect after logout

},

},

}

```

Common Pitfalls

Callback URL Mismatch

Problem: redirect_uri_mismatch error from provider

Fix: Ensure callback URL exactly matches provider dashboard:

```

# Provider dashboard (Google/GitHub)

http://localhost:7654/api/auth/google/callback

# Must match Bknd host configuration

host: "http://localhost:7654"

```

Missing Environment Variables

Problem: OAuth login fails silently

Fix: Verify all required env vars are set:

```bash

# Required for Google OAuth

GOOGLE_CLIENT_ID=...

GOOGLE_CLIENT_SECRET=...

# Required for GitHub OAuth

GITHUB_CLIENT_ID=...

GITHUB_CLIENT_SECRET=...

# Always required

JWT_SECRET=...

```

CORS Issues (SPA)

Problem: CORS error when calling OAuth endpoints

Fix: Configure CORS on backend:

```typescript

{

server: {

cors: {

origin: ["http://localhost:3000"], // Your frontend URL

credentials: true,

},

},

}

```

Strategy Conflict

Problem: "User signed up with different strategy"

Cause: User has existing account with different auth method

Solution: Users can only have ONE strategy. Guide them to use their original login method or implement account linking (requires custom code).

OAuth Cookie Not Set

Problem: Cookie not received after OAuth callback

Fix: Ensure secure cookie settings:

```typescript

{

auth: {

cookie: {

secure: false, // Set false for localhost (no HTTPS)

sameSite: "lax", // Required for OAuth redirects

},

},

}

```

Invalid Scopes

Problem: Provider rejects scope request

Fix: Use only scopes from scopes_supported:

```typescript

// Google OIDC defaults

scopes_supported: ["openid", "email", "profile"]

// GitHub OAuth2 defaults

scopes_supported: ["read:user", "user:email"]

```

Verification

Test OAuth setup:

1. Check available strategies:

```bash

curl http://localhost:7654/api/auth/strategies

```

Response should include your OAuth providers:

```json

{

"strategies": ["password", "google", "github"],

"basepath": "/api/auth"

}

```

2. Test OAuth URL generation:

```bash

curl http://localhost:7654/api/auth/google/login

```

Response:

```json

{

"url": "https://accounts.google.com/o/oauth2/v2/auth?...",

"challenge": "...",

"action": "login"

}

```

3. Complete full OAuth flow:

  • Visit the OAuth URL in browser
  • Complete provider login
  • Verify redirect to pathSuccess
  • Check api/auth/me returns user

DOs and DON'Ts

DO:

  • Store client secrets in environment variables
  • Use HTTPS in production
  • Set sameSite: "lax" for cookie (required for OAuth redirects)
  • Match callback URLs exactly in provider dashboard
  • Test OAuth flow in incognito (avoid cached sessions)
  • Set appropriate JWT expiration

DON'T:

  • Hardcode client secrets in code
  • Use secure: true cookie on localhost (no HTTPS)
  • Mix up client_id and client_secret
  • Forget to update callback URLs for production
  • Expect users to have multiple strategies (one per user)
  • Skip the challenge verification in token flow

Related Skills

  • bknd-setup-auth - Initialize authentication system
  • bknd-login-flow - Login/logout functionality
  • bknd-registration - User registration setup
  • bknd-session-handling - Manage user sessions
  • bknd-create-role - Define user roles for OAuth users