9.6 KiB
9.6 KiB
Challonge OAuth Setup Guide
Complete guide to implementing OAuth authentication for Challonge API v2.1 APPLICATION scope.
Quick Start
Development Setup (5 minutes)
-
Register OAuth Application
- Visit https://connect.challonge.com
- Create new application
- Set redirect URI:
http://localhost:5173/oauth/callback - Note your Client ID and Client Secret
-
Configure Environment
cp .env.example .envEdit
.env:# Frontend (Vite variables) VITE_CHALLONGE_CLIENT_ID=your_client_id_here VITE_CHALLONGE_REDIRECT_URI=http://localhost:5173/oauth/callback # Backend (OAuth Proxy) CHALLONGE_CLIENT_ID=your_client_id_here CHALLONGE_CLIENT_SECRET=your_client_secret_here CHALLONGE_REDIRECT_URI=http://localhost:5173/oauth/callback OAUTH_PROXY_PORT=3001 -
Install Dependencies
npm install -
Run Development Servers
# Option 1: Run both servers with one command npm run dev:full # Option 2: Run separately in two terminals # Terminal 1 - Frontend npm run dev # Terminal 2 - OAuth Proxy npm run oauth-proxy -
Test OAuth Flow
- Visit http://localhost:5173/challonge-test
- Click "Connect with OAuth"
- Authorize the app on Challonge
- You'll be redirected back with tokens
- Now you can use APPLICATION scope!
Architecture
┌─────────────────┐
│ Vue Frontend │
│ localhost:5173 │
└────────┬────────┘
│
├─→ User clicks "Connect with OAuth"
│ Redirect to Challonge authorization URL
│
├─→ User authorizes on Challonge
│ Redirect back to /oauth/callback?code=xxx&state=yyy
│
├─→ Frontend calls /api/oauth/token
│
┌────────▼────────┐
│ OAuth Proxy │
│ localhost:3001 │
└────────┬────────┘
│
├─→ Exchange code for tokens (includes client_secret)
│ POST https://api.challonge.com/oauth/token
│
└─→ Return tokens to frontend
Frontend stores in localStorage
Creates v2.1 client with Bearer token
Files Created
Backend
- server/oauth-proxy.js - Express server for OAuth token exchange
/oauth/token- Exchange authorization code/oauth/refresh- Refresh expired tokens/health- Health check endpoint
Frontend
-
src/composables/useChallongeOAuth.js - OAuth state management
- Token storage and retrieval
- Authorization URL generation
- Automatic token refresh
- CSRF protection
-
src/views/OAuthCallback.vue - OAuth redirect handler
- Processes authorization callback
- Displays loading/success/error states
- Auto-redirects to Challonge Test
Configuration
- vite.config.js - Added
/api/oauthproxy - src/router/index.js - Added
/oauth/callbackroute - package.json - Added dependencies and scripts
- .env.example - OAuth configuration template
Environment Variables
Frontend (Vite - PUBLIC)
VITE_CHALLONGE_CLIENT_ID=xxx # OAuth Client ID (public)
VITE_CHALLONGE_REDIRECT_URI=xxx # Callback URL
Backend (OAuth Proxy - PRIVATE)
CHALLONGE_CLIENT_ID=xxx # OAuth Client ID
CHALLONGE_CLIENT_SECRET=xxx # OAuth Client Secret (NEVER expose)
CHALLONGE_REDIRECT_URI=xxx # Must match registered URL
OAUTH_PROXY_PORT=3001 # Proxy server port
Production (Optional)
NODE_ENV=production
FRONTEND_URL=https://yourdomain.com
Production Deployment
Option 1: Express Server (Simple)
Deploy server/oauth-proxy.js to:
- Heroku
- Railway
- DigitalOcean App Platform
- AWS EC2/ECS
Update production .env:
NODE_ENV=production
FRONTEND_URL=https://yourdomain.com
CHALLONGE_CLIENT_ID=xxx
CHALLONGE_CLIENT_SECRET=xxx
CHALLONGE_REDIRECT_URI=https://yourdomain.com/oauth/callback
PORT=3000
Update frontend build environment:
VITE_CHALLONGE_CLIENT_ID=xxx
VITE_CHALLONGE_REDIRECT_URI=https://yourdomain.com/oauth/callback
Option 2: Serverless Functions (Scalable)
Convert server/oauth-proxy.js to serverless functions:
Netlify Functions (netlify/functions/oauth-token.js):
import fetch from 'node-fetch';
export async function handler(event) {
if (event.httpMethod !== 'POST') {
return { statusCode: 405, body: 'Method Not Allowed' };
}
const { code } = JSON.parse(event.body);
const response = await fetch('https://api.challonge.com/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
client_id: process.env.CHALLONGE_CLIENT_ID,
client_secret: process.env.CHALLONGE_CLIENT_SECRET,
code: code,
redirect_uri: process.env.CHALLONGE_REDIRECT_URI,
}),
});
const data = await response.json();
return {
statusCode: response.status,
body: JSON.stringify(data),
};
}
Vercel Functions (api/oauth/token.js):
import fetch from 'node-fetch';
export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method Not Allowed' });
}
const { code } = req.body;
const response = await fetch('https://api.challonge.com/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
client_id: process.env.CHALLONGE_CLIENT_ID,
client_secret: process.env.CHALLONGE_CLIENT_SECRET,
code: code,
redirect_uri: process.env.CHALLONGE_REDIRECT_URI,
}),
});
const data = await response.json();
res.status(response.status).json(data);
}
Option 3: Cloudflare Workers (Edge)
export default {
async fetch(request, env) {
if (request.method !== 'POST') {
return new Response('Method Not Allowed', { status: 405 });
}
const { code } = await request.json();
const response = await fetch('https://api.challonge.com/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
client_id: env.CHALLONGE_CLIENT_ID,
client_secret: env.CHALLONGE_CLIENT_SECRET,
code: code,
redirect_uri: env.CHALLONGE_REDIRECT_URI,
}),
});
return response;
}
};
Security Best Practices
✅ DO
- Store client_secret ONLY on backend (never in frontend)
- Use HTTPS in production
- Validate state parameter for CSRF protection
- Store tokens in localStorage (XSS protection via CSP)
- Set appropriate token expiration
- Implement token refresh before expiration
- Use environment variables for secrets
❌ DON'T
- Never commit
.envto version control - Never expose client_secret in frontend code
- Never log tokens in production
- Don't use OAuth without SSL in production
- Don't store tokens in cookies (CSRF risk)
Testing
Test OAuth Flow
- Start both servers:
npm run dev:full - Visit http://localhost:5173/challonge-test
- Click "Connect with OAuth"
- Should redirect to Challonge
- Authorize the app
- Should redirect back to callback
- Should see success message
- Should redirect to Challonge Test
- OAuth status should show "Connected"
- Try listing tournaments with "Show all tournaments" checked
Test Token Refresh
// In browser console after connecting
const { refreshToken } = useChallongeOAuth();
await refreshToken(); // Should refresh token
Test Logout
// In browser console
const { logout } = useChallongeOAuth();
logout(); // Should clear tokens
Troubleshooting
"Missing required environment variables"
- Check
.envfile exists in project root - Verify
CHALLONGE_CLIENT_IDandCHALLONGE_CLIENT_SECRETare set - Restart OAuth proxy after changing
.env
"Invalid state parameter"
- Clear browser storage and try again
- Verify redirect URI matches exactly
"Token exchange failed"
- Check client ID and secret are correct
- Verify redirect URI matches registered URL exactly
- Check OAuth proxy is running on port 3001
- Look at OAuth proxy console for error details
"CORS errors"
- Verify Vite proxy is configured correctly
- Check OAuth proxy CORS settings
- Ensure frontend URL is allowed in production
"Token expired"
- Token should auto-refresh when needed
- Manually refresh:
useChallongeOAuth().refreshToken() - If refresh fails, user must re-authenticate
API Scopes
Available scopes for Challonge OAuth:
tournaments:read- Read tournament datatournaments:write- Create/update tournamentsparticipants:read- Read participant dataparticipants:write- Manage participantsmatches:read- Read match datamatches:write- Update match resultsuser:read- Read user profile
Default scope in app: tournaments:read tournaments:write
Next Steps
- ✅ Basic OAuth flow working
- ✅ Token storage and refresh
- ✅ APPLICATION scope access
- 🔄 Add scope selector in UI (optional)
- 🔄 Implement token refresh UI indicator
- 🔄 Add "time until expiration" display
- 🔄 Deploy to production
- 🔄 Add more scopes as needed
Support
- Challonge API Docs: https://challonge.apidog.io
- OAuth 2.0 Spec: https://oauth.net/2/
- Register Apps: https://connect.challonge.com