Skip to content

Commit b8fa179

Browse files
committed
docs: added documentation about the PKCE methods
1 parent 908f326 commit b8fa179

File tree

2 files changed

+207
-85
lines changed

2 files changed

+207
-85
lines changed
Lines changed: 202 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,146 +1,265 @@
11
---
22
title: Authentication
3-
description: Learn how to authenticate with the Stack Overflow API to use the SDK.
3+
description: Learn how to authenticate with the Stack Overflow API using the built-in authentication helpers.
44
---
55
import { Card, CardGrid } from '@astrojs/starlight/components';
66

7-
The Stack Overflow SDK requires an access token to authenticate API requests. This guide explains how to obtain and use access tokens with the SDK.
7+
The Stack Overflow SDK provides built-in authentication helpers that simplify the OAuth 2.0 flow with PKCE for secure token generation. Authentication requirements vary by Stack Overflow for Teams tier.
88

9-
## Overview
9+
### Authentication by Tier
1010

11-
The SDK uses OAuth 2.0 with access tokens for authentication. All API calls require a valid access token to be passed during SDK initialization.
11+
- **Stack Overflow for Teams Enterprise** - Supports OAuth 2.0 with PKCE. Access tokens can be generated dynamically. You can optionally provide a single Access Token manually.
12+
- **Stack Overflow for Teams Basic/Business** - OAuth is not available. Manual input of Access tokens (PATs) are **required** in order to use the SDK.
1213

14+
### Authentication Clients
15+
16+
The SDK includes two authentication clients for Enterprise instances:
17+
- **BackendAuthClient** - For server-side Node.js environments with full PKCE implementation
18+
- **FrontendAuthClient** - For browser environments that communicate with your backend API
19+
20+
### SDK Initialization Options
21+
22+
#### Enterprise - With OAuth Setup
1323
```typescript
14-
import StackOverflowSDK from 'so-teams-sdk;
24+
import StackOverflowSDK from 'so-teams-sdk';
1525

26+
// Option 1: OAuth configuration (no token required initially)
1627
const sdk = new StackOverflowSDK({
17-
baseUrl: 'https://[your-site].stackenterprise.co',
18-
accessToken: 'your-access-token-here'
28+
baseUrl: 'https://your-site.stackenterprise.co',
29+
auth: {
30+
clientId: 'your-client-id',
31+
redirectUri: 'https://yourapp.com/callback',
32+
baseUrl: 'https://your-site.stackenterprise.co',
33+
scope: 'read_inbox write_access'
34+
}
1935
});
20-
```
2136

22-
## Obtaining Access Tokens
37+
// Option 2: With existing access token
38+
const sdk = StackOverflowSDK.fromToken(
39+
'your-access-token',
40+
'https://your-site.stackenterprise.co'
41+
);
42+
43+
// Option 3: Factory method for OAuth setup
44+
const sdk = StackOverflowSDK.enterpriseOAuth({
45+
clientId: 'your-client-id',
46+
redirectUri: 'https://yourapp.com/callback',
47+
baseUrl: 'https://your-site.stackenterprise.co'
48+
});
49+
```
2350

24-
### For Stack Overflow for Teams Enterprise
51+
#### Basic/Business - Personal Access Token Required
52+
```typescript
53+
import StackOverflowSDK from 'so-teams-sdk';
2554

26-
If you're using Stack Overflow for Teams Enterprise, follow the comprehensive OAuth implementation guide to generate secure API tokens:
55+
// PAT is mandatory for Basic/Business tiers
56+
const sdk = StackOverflowSDK.fromToken(
57+
'your-personal-access-token',
58+
'https://api.stackoverflowteams.com/v3'
59+
);
2760

28-
**[Secure API Token Generation with OAuth and PKCE →](https://stackoverflow.help/en/articles/19820283-secure-api-token-generation-with-oauth-and-pkce)**
61+
// Team context is required for Basic/Business operations
62+
const teamContext = sdk.forTeam('your-team-id');
63+
const questions = await teamContext.questions.getAll();
64+
```
2965

30-
This guide covers:
31-
- OAuth Authorization Code flow
32-
- PKCE (Proof Key for Code Exchange) implementation
33-
- Token generation and management
34-
- Security best practices
66+
## Authentication Clients (Enterprise Only)
3567

36-
### For Stack Overflow for Teams
68+
:::note[Enterprise Feature]
69+
Authentication clients are only available for Stack Overflow for Teams Enterprise instances. Basic/Business tiers must use Personal Access Tokens during SDK initialization.
70+
:::
3771

38-
If you're using Stack Overflow for Teams (Business or Basic), the process is simpler. You can generate a Personal Access Token (PAT) by following this guide:
72+
### Backend Authentication (Server-Side)
3973

40-
**[Personal Access Tokens (PATs) for API Authentication →](https://stackoverflowteams.help/en/articles/10908790-personal-access-tokens-pats-for-api-authentication)**
74+
The `BackendAuthClient` handles the complete OAuth flow with PKCE on your server:
4175

42-
PATs allow you to authenticate securely with the API without needing the full OAuth flow.
76+
```typescript title="backend-auth.ts"
77+
import { BackendAuthClient } from 'so-teams-sdk';
4378

44-
## Using Access Tokens
79+
const authClient = new BackendAuthClient({
80+
clientId: 'your-client-id',
81+
redirectUri: 'https://yourapp.com/callback',
82+
baseUrl: 'https://your-site.stackenterprise.co',
83+
scope: 'read_inbox write_access' // Optional
84+
});
4585

46-
Once you have an access token, initialize the SDK with your credentials:
86+
// Generate authorization URL
87+
const { url, codeVerifier, state } = await authClient.getAuthUrl();
4788

48-
```typescript title="sdk-setup.ts"
49-
import StackOverflowSDK from 'so-teams-sdk;
89+
// Store codeVerifier and state securely (session, database, etc.)
90+
// Redirect user to the authorization URL
5091

51-
// For Stack Overflow for Teams
52-
const teamsSDK = new StackOverflowSDK({
53-
baseUrl: 'https://your-site.stackenterprise.co',
54-
accessToken: 'your-access-token'
55-
});
92+
// In your callback handler:
93+
const tokens = await authClient.exchangeCodeForToken(
94+
callbackCode,
95+
storedCodeVerifier
96+
);
5697

98+
// Validate state for CSRF protection
99+
const isValidState = authClient.validateState(callbackState, storedState);
57100
```
58101

59-
## Token Scopes
102+
### Frontend Authentication (Browser)
60103

61-
Different API operations require different scopes. Common scopes include:
104+
The `FrontendAuthClient` communicates with your backend API to handle OAuth securely:
62105

63-
| Scope | Description |
64-
|-------|-------------|
65-
| read_inbox | Access user's inbox |
66-
| write_access | Perform write operations |
67-
| private_info | Access private user data |
68-
| no_expiry | Token never expires (use with caution) |
106+
```typescript title="frontend-auth.ts"
107+
import { FrontendAuthClient } from 'so-teams-sdk';
69108

70-
## Environment Variables
109+
const frontendClient = new FrontendAuthClient({
110+
clientId: 'your-client-id',
111+
redirectUri: 'https://yourapp.com/callback',
112+
baseUrl: 'https://your-site.stackenterprise.co'
113+
}, '/api'); // Your backend API base URL
71114

72-
For security, store your access tokens in environment variables:
115+
// Start authentication flow
116+
const authUrl = await frontendClient.startAuth();
117+
window.location.href = authUrl;
73118

74-
```typescript title="config.ts"
75-
export const config = {
76-
baseUrl: process.env.STACKOVERFLOW_BASE_URL,
77-
accessToken: process.env.STACKOVERFLOW_ACCESS_TOKEN
78-
};
119+
// Handle OAuth callback
120+
await frontendClient.handleCallback();
121+
122+
// Check authentication status
123+
const isAuthenticated = await frontendClient.getAuthStatus();
124+
125+
// Manual token submission (for PATs)
126+
const success = await frontendClient.submitAccessToken(userToken);
79127
```
80128

81-
```typescript title="app.ts"
82-
import StackOverflowSDK from 'so-teams-sdk;
83-
import { config } from './config';
129+
## Authentication Configuration
84130

85-
const sdk = new StackOverflowSDK(config);
131+
### AuthConfig Interface
132+
133+
```typescript
134+
interface AuthConfig {
135+
/** OAuth client ID from Stack Overflow Enterprise */
136+
clientId: string;
137+
/** Redirect URI registered with your application */
138+
redirectUri: string;
139+
/** Stack Overflow Enterprise instance URL */
140+
baseUrl: string;
141+
/** OAuth scopes (optional) */
142+
scope?: string;
143+
}
86144
```
87145

88-
## Token Management
146+
### Available Methods
147+
148+
#### BackendAuthClient Methods
149+
150+
| Method | Description | Returns |
151+
|--------|-------------|---------|
152+
| `generatePKCETokens()` | Generate PKCE tokens for secure OAuth | `Promise<PKCETokens>` |
153+
| `getAuthUrl()` | Generate authorization URL with PKCE | `Promise<{url, codeVerifier, state}>` |
154+
| `exchangeCodeForToken()` | Exchange auth code for access token | `Promise<TokenResponse>` |
155+
| `validateState()` | Validate state parameter for CSRF protection | `boolean` |
156+
157+
#### FrontendAuthClient Methods
158+
159+
| Method | Description | Returns |
160+
|--------|-------------|---------|
161+
| `startAuth()` | Start OAuth flow via backend API | `Promise<string>` |
162+
| `completeAuth()` | Complete OAuth with callback params | `Promise<void>` |
163+
| `handleCallback()` | Handle OAuth callback in current page | `Promise<void>` |
164+
| `getAuthStatus()` | Check if user is authenticated | `Promise<boolean>` |
165+
| `submitAccessToken()` | Submit manual access token | `Promise<boolean>` |
166+
| `logout()` | Clear authentication state | `Promise<boolean>` |
167+
168+
## Token Scopes
169+
170+
Different API operations require different scopes:
89171

90-
### Token Expiration
172+
| Scope | Description |
173+
|-------|-------------|
174+
| read_inbox | Access user's inbox |
175+
| write_access | Perform write operations |
176+
| private_info | Access private user data |
177+
| no_expiry | Token never expires (use with caution) |
178+
179+
## Security Best Practices
91180

92-
Unless you use the `no_expiry` scope, access tokens expire after 24 hours. Monitor token expiration and implement refresh logic as needed.
181+
<CardGrid>
182+
<Card title="PKCE Implementation" icon="shield">
183+
The SDK automatically implements PKCE (Proof Key for Code Exchange) to prevent authorization code interception attacks.
184+
</Card>
185+
<Card title="State Validation" icon="lock">
186+
Always validate the state parameter in OAuth callbacks to prevent CSRF attacks using the built-in validation methods.
187+
</Card>
188+
<Card title="Secure Token Storage" icon="certificate">
189+
Follow secure token storage best practices and avoid client-side storage for sensitive authentication data.
190+
</Card>
191+
<Card title="Environment Variables" icon="key">
192+
Keep sensitive configuration like client IDs and secrets in environment variables, not in your source code.
193+
</Card>
194+
</CardGrid>
93195

94-
### Error Handling
196+
## Error Handling
95197

96198
Handle authentication errors gracefully:
97199

98200
```typescript title="auth-error-handling.ts"
99-
async function makeAuthenticatedRequest() {
201+
async function authenticateUser() {
100202
try {
101-
const questions = await sdk.questions.getQuestions();
102-
return questions;
203+
const authUrl = await authClient.getAuthUrl();
204+
// Handle success
103205
} catch (error) {
104-
if (error.status === 401) {
105-
console.error('Authentication failed - token may be expired or invalid');
106-
// Implement token refresh or re-authentication logic
107-
} else if (error.status === 403) {
108-
console.error('Insufficient permissions - check token scopes');
206+
if (error.message.includes('clientId')) {
207+
console.error('Missing OAuth configuration');
208+
} else {
209+
console.error('Authentication setup failed:', error);
109210
}
110-
throw error;
111211
}
112212
}
213+
214+
// In callback handler
215+
try {
216+
const tokens = await authClient.exchangeCodeForToken(code, codeVerifier);
217+
} catch (error) {
218+
if (error.message.includes('Failed to exchange')) {
219+
console.error('Token exchange failed - check OAuth configuration');
220+
}
221+
throw error;
222+
}
113223
```
114224

115-
## Security Best Practices
225+
## Alternative: Personal Access Tokens
116226

117-
<CardGrid>
118-
<Card title="Secure Storage" icon="lock">
119-
Never hardcode access tokens in your source code. Use environment variables or secure configuration management.
120-
</Card>
121-
<Card title="Token Rotation" icon="refresh">
122-
Regularly rotate your access tokens and implement proper token lifecycle management.
123-
</Card>
124-
<Card title="Scope Limitation" icon="shield">
125-
Request only the minimum scopes required for your application functionality.
126-
</Card>
127-
<Card title="HTTPS Only" icon="certificate">
128-
Always use HTTPS when transmitting access tokens to prevent interception.
129-
</Card>
130-
</CardGrid>
227+
### Enterprise Instances
228+
For simpler Enterprise implementations, you can generate Tokens manually and use them as seen below:
229+
230+
```typescript
231+
const sdk = StackOverflowSDK.fromToken(
232+
'your-enterprise-pat',
233+
'https://your-site.stackenterprise.co'
234+
);
235+
236+
const questions = await sdk.questions.getAll();
237+
```
238+
239+
You'll need to follow [this guide](https://stackoverflowteams.help/en/articles/9718149-secure-api-token-generation-with-oauth-and-pkce) to understand how OAuth works on Enterprise.
240+
241+
### Basic/Business Instances (Required)
242+
For Basic and Business tiers, PATs are the only authentication method available:
243+
244+
**[Personal Access Tokens (PATs) for API Authentication →](https://stackoverflowteams.help/en/articles/10908790-personal-access-tokens-pats-for-api-authentication)**
245+
246+
```typescript
247+
const sdk = StackOverflowSDK.fromToken(userProvidedPAT, 'https://api.stackoverflowteams.com/v3');
248+
const teamContext = sdk.forTeam('team-123');
249+
```
131250

132251
## Next Steps
133252

134-
Once you have your access token configured:
253+
Once you have authentication configured with the helpers:
135254

136-
- [Quickstart Guide](/quickstart) - Get started with the SDK
137-
- [Questions API](/questions/getall/) - Learn about fetching questions
138-
- [Rate Limits](/guides/rate-limiting) - Understand how rate limits work on SO Teams
255+
- [Quickstart Guide](/guides/quickstart) - Get started with the SDK
256+
- [Questions API](/questions/getall/) - Learn about fetching questions
257+
- [Rate Limits](/guides/rate-limiting) - Understand API rate limits
139258

140259
:::note[Rate Limits]
141-
Authentication doesn't bypass API rate limits. Authenticated requests typically have higher rate limits than anonymous requests, but limits still apply.
260+
Authentication doesn't bypass API rate limits.
142261
:::
143262

144263
:::tip[Development vs Production]
145-
Use different access tokens for development and production environments. Consider using shorter-lived tokens in production for enhanced security.
264+
Use different OAuth applications and tokens for development and production environments. The authentication helpers support this through environment-specific configuration.
146265
:::

docs/src/content/docs/index.mdx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ import { Card, CardGrid } from '@astrojs/starlight/components';
4848
<Card title="Type Safety" icon="laptop">
4949
Complete TypeScript definitions for all Teams endpoints, models, and responses.
5050
</Card>
51+
<Card title="PKCE Authentication Built-in" icon="approve-check-circle">
52+
Includes full PKCE authentication with ready-to-use helpers for both backend and frontend implementations.
53+
</Card>
5154
</CardGrid>
5255

5356
## Popular use cases
@@ -65,8 +68,8 @@ Whether you're building internal tools, integrating with existing workflows, or
6568
## Current status
6669

6770
At the moment, the SDK is only available as a **TypeScript library**.
68-
This project is in **early access**, and more language support and features (such as authentication helpers and rate limiting) will be added in the future.
71+
This project is in **early access**, and more language support and features (such as rate limiting) will be added in the future.
6972

7073
## Ready to start building?
7174

72-
Our SDK provides a higher-level abstraction for programmatically interacting with Stack Overflow for Teams, removing friction and enabling you to focus on building great experiences for your team.
75+
Our SDK provides a higher-level abstraction for programmatically interacting with Stack Overflow for Teams, removing friction and enabling you to focus on building great experiences for your team.

0 commit comments

Comments
 (0)