export interface OAuthExample { id: string; label: string; language: string; code: string; } export function buildOAuthExamples(apiBase: string): OAuthExample[] { const API_BASE = apiBase.replace(/\/+$/, ''); return [ { id: 'javascript', label: 'JavaScript', language: 'javascript', code: `// Authorization Code Flow (Node.js / браузер) const clientId = 'YOUR_CLIENT_ID'; const redirectUri = 'https://app.example.com/oauth/callback'; const scope = 'openid profile email'; const state = crypto.randomUUID(); // Шаг 1: перенаправить пользователя на IdP const authorizeUrl = new URL('${API_BASE}/oauth/authorize'); authorizeUrl.searchParams.set('userId', 'USER_ID_AFTER_LOGIN'); authorizeUrl.searchParams.set('clientId', clientId); authorizeUrl.searchParams.set('redirectUri', redirectUri); authorizeUrl.searchParams.set('scope', scope); authorizeUrl.searchParams.set('state', state); window.location.href = authorizeUrl.toString(); // OIDC Discovery (issuer = PUBLIC_API_URL из настроек админки) // GET ${API_BASE}/.well-known/openid-configuration // Шаг 2: обменять code на токены (на backend!) const tokenResponse = await fetch('${API_BASE}/oauth/token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ grantType: 'authorization_code', code: 'AUTHORIZATION_CODE', clientId, clientSecret: 'YOUR_CLIENT_SECRET', redirectUri }) }); const tokens = await tokenResponse.json(); // Шаг 3: получить профиль const profile = await fetch('${API_BASE}/oauth/userinfo', { headers: { Authorization: \`Bearer \${tokens.accessToken}\` } }).then((r) => r.json());` }, { id: 'typescript-next', label: 'Next.js', language: 'typescript', code: `// app/api/oauth/callback/route.ts import { NextRequest, NextResponse } from 'next/server'; const ISSUER = '${API_BASE}'; export async function GET(request: NextRequest) { const code = request.nextUrl.searchParams.get('code'); if (!code) return NextResponse.redirect('/login?error=oauth'); const tokenRes = await fetch(\`\${ISSUER}/oauth/token\`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ grantType: 'authorization_code', code, clientId: process.env.OAUTH_CLIENT_ID, clientSecret: process.env.OAUTH_CLIENT_SECRET, redirectUri: process.env.OAUTH_REDIRECT_URI }) }); const tokens = await tokenRes.json(); const response = NextResponse.redirect('/dashboard'); response.cookies.set('access_token', tokens.accessToken, { httpOnly: true, secure: true }); return response; }` }, { id: 'python', label: 'Python', language: 'python', code: `import requests from urllib.parse import urlencode API_BASE = '${API_BASE}' CLIENT_ID = 'YOUR_CLIENT_ID' CLIENT_SECRET = 'YOUR_CLIENT_SECRET' REDIRECT_URI = 'https://app.example.com/oauth/callback' # OIDC Discovery discovery = requests.get(f'{API_BASE}/.well-known/openid-configuration', timeout=15).json() params = urlencode({ 'userId': 'USER_ID', 'clientId': CLIENT_ID, 'redirectUri': REDIRECT_URI, 'scope': 'openid profile email', 'state': 'random-state' }) authorize_url = f'{API_BASE}/oauth/authorize?{params}' token_response = requests.post(f'{API_BASE}/oauth/token', json={ 'grantType': 'authorization_code', 'code': 'AUTHORIZATION_CODE', 'clientId': CLIENT_ID, 'clientSecret': CLIENT_SECRET, 'redirectUri': REDIRECT_URI }, timeout=15) tokens = token_response.json() profile = requests.get( f'{API_BASE}/oauth/userinfo', headers={'Authorization': f"Bearer {tokens['accessToken']}"}, timeout=15 ).json()` }, { id: 'php', label: 'PHP', language: 'php', code: ` 'USER_ID', 'clientId' => $clientId, 'redirectUri' => $redirectUri, 'scope' => 'openid profile email', 'state' => bin2hex(random_bytes(16)), ]); header('Location: ' . $apiBase . '/oauth/authorize?' . $params); exit;` }, { id: 'go', label: 'Go', language: 'go', code: `package main import ( "bytes" "encoding/json" "net/http" "net/url" ) const apiBase = "${API_BASE}" func buildAuthorizeURL(userID, clientID, redirectURI, scope, state string) string { q := url.Values{} q.Set("userId", userID) q.Set("clientId", clientID) q.Set("redirectUri", redirectURI) q.Set("scope", scope) q.Set("state", state) return apiBase + "/oauth/authorize?" + q.Encode() }` }, { id: 'csharp', label: 'C#', language: 'csharp', code: `using System.Net.Http.Json; var apiBase = "${API_BASE}"; var clientId = Environment.GetEnvironmentVariable("OAUTH_CLIENT_ID"); var redirectUri = "https://app.example.com/oauth/callback"; var discovery = await new HttpClient().GetFromJsonAsync>( $"{apiBase}/.well-known/openid-configuration"); var authorizeUrl = $"{apiBase}/oauth/authorize?userId=USER_ID&clientId={clientId}" + $"&redirectUri={Uri.EscapeDataString(redirectUri)}&scope=openid profile email&state=xyz";` }, { id: 'curl', label: 'cURL', language: 'bash', code: `# OIDC Discovery (issuer = ${API_BASE}) curl ${API_BASE}/.well-known/openid-configuration # Authorization (браузер пользователя) open "${API_BASE}/oauth/authorize?userId=USER_ID&clientId=CLIENT_ID&redirectUri=https%3A%2F%2Fapp.example.com%2Fcallback&scope=openid%20profile%20email&state=xyz" # Обмен code на токены curl -X POST ${API_BASE}/oauth/token \\ -H "Content-Type: application/json" \\ -d '{ "grantType": "authorization_code", "code": "AUTHORIZATION_CODE", "clientId": "CLIENT_ID", "clientSecret": "CLIENT_SECRET", "redirectUri": "https://app.example.com/callback" }' # UserInfo curl ${API_BASE}/oauth/userinfo \\ -H "Authorization: Bearer ACCESS_TOKEN"` } ]; } /** @deprecated Используйте buildOAuthExamples(apiBase) */ export const oauthExamples = buildOAuthExamples('http://localhost:3000');