oauth
SKILL.md
OAuth 2.0
Authorization framework for secure delegated access.
When to Use
- Third-party authentication
- API authorization
- Single sign-on (SSO)
- Social login integration
Quick Start
// Authorization Code Flow
const authUrl = new URL("https://auth.example.com/authorize");
authUrl.searchParams.set("client_id", CLIENT_ID);
authUrl.searchParams.set("redirect_uri", REDIRECT_URI);
authUrl.searchParams.set("response_type", "code");
authUrl.searchParams.set("scope", "openid profile email");
authUrl.searchParams.set("state", generateState());
authUrl.searchParams.set("code_challenge", generateCodeChallenge());
authUrl.searchParams.set("code_challenge_method", "S256");
window.location.href = authUrl.toString();
Core Concepts
Authorization Code with PKCE
// 1. Generate PKCE verifier and challenge
function generateCodeVerifier(): string {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return base64UrlEncode(array);
}
async function generateCodeChallenge(verifier: string): Promise<string> {
const hash = await crypto.subtle.digest(
"SHA-256",
new TextEncoder().encode(verifier),
);
return base64UrlEncode(new Uint8Array(hash));
}
// 2. Exchange code for tokens
async function exchangeCodeForTokens(code: string, verifier: string) {
const response = await fetch("https://auth.example.com/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "authorization_code",
code,
redirect_uri: REDIRECT_URI,
client_id: CLIENT_ID,
code_verifier: verifier,
}),
});
return response.json();
}
Token Refresh
async function refreshTokens(refreshToken: string) {
const response = await fetch("https://auth.example.com/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "refresh_token",
refresh_token: refreshToken,
client_id: CLIENT_ID,
}),
});
return response.json();
}
Common Patterns
Protected API Calls
async function fetchWithAuth(url: string, accessToken: string) {
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
if (response.status === 401) {
// Token expired, refresh and retry
const newTokens = await refreshTokens(getRefreshToken());
saveTokens(newTokens);
return fetchWithAuth(url, newTokens.access_token);
}
return response.json();
}
Best Practices
Do:
- Use PKCE for all public clients
- Store tokens securely
- Implement token refresh
- Validate state parameter
Don't:
- Store tokens in localStorage
- Use implicit flow
- Skip HTTPS
- Ignore token expiration
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| Invalid grant | Code expired | Retry auth flow |
| CORS error | Wrong redirect | Check allowed origins |
| Token rejected | Clock skew | Sync server time |
References
Weekly Installs
2
Repository
g1joshi/agent-skillsGitHub Stars
7
First Seen
Feb 10, 2026
Security Audits
Installed on
mcpjam2
claude-code2
replit2
junie2
windsurf2
zencoder2