[{"data":1,"prerenderedAt":409},["ShallowReactive",2],{"blog-prompts/add-oauth-security":3},{"id":4,"title":5,"body":6,"category":388,"date":389,"dateModified":390,"description":391,"draft":392,"extension":393,"faq":394,"featured":392,"headerVariant":395,"image":394,"keywords":394,"meta":396,"navigation":397,"ogDescription":398,"ogTitle":394,"path":399,"readTime":394,"schemaOrg":400,"schemaType":401,"seo":402,"sitemap":403,"stem":404,"tags":405,"twitterCard":407,"__hash__":408},"blog/blog/prompts/add-oauth-security.md","Add OAuth Security with AI Prompts",{"type":7,"value":8,"toc":378},"minimark",[9,16,21,24,96,100,103,148,158,162,165,230,234,237,300,309,325,329,332,352,366],[10,11,12],"tldr",{},[13,14,15],"p",{},"OAuth is complex and easy to get wrong. Always use the state parameter, validate tokens server-side, use PKCE for public clients, and don't trust data from ID tokens without verification. These prompts help you implement OAuth without the common security holes.",[17,18,20],"h2",{"id":19},"secure-oauth-flow-setup","Secure OAuth Flow Setup",[13,22,23],{},"Copy this prompt to implement an OAuth login flow with proper CSRF protection via the state parameter. Your AI will generate the full authorization redirect, state generation and session storage, callback verification, and replay-attack prevention.",[25,26,28,31,42,45,61,64,81,84],"prompt-box",{"title":27},"OAuth with State Parameter",[13,29,30],{},"Implement OAuth login with proper CSRF protection.",[13,32,33,34,38,39],{},"Provider: ",[35,36,37],"span",{},"Google/GitHub/Discord","\nFramework: ",[35,40,41],{},"Next.js/Express",[13,43,44],{},"Authorization request must include:",[46,47,48,52,55,58],"ol",{},[49,50,51],"li",{},"state: cryptographically random value",[49,53,54],{},"Store state in session before redirect",[49,56,57],{},"Verify state matches on callback",[49,59,60],{},"Use state only once",[13,62,63],{},"Implementation:",[46,65,66,69,72,75,78],{},[49,67,68],{},"Generate state: crypto.randomBytes(32).toString('hex')",[49,70,71],{},"Store in session: session.oauthState = state",[49,73,74],{},"Include in auth URL: &state={state}",[49,76,77],{},"On callback: verify req.query.state === session.oauthState",[49,79,80],{},"Delete state from session after verification",[13,82,83],{},"Reject callback if:",[85,86,87,90,93],"ul",{},[49,88,89],{},"State is missing",[49,91,92],{},"State doesn't match session",[49,94,95],{},"State was already used",[17,97,99],{"id":98},"pkce-for-public-clients","PKCE for Public Clients",[13,101,102],{},"Use this prompt to add PKCE (Proof Key for Code Exchange) to your OAuth flow. Your AI will generate code verifier and challenge creation, the modified authorization URL, and the token exchange logic that prevents authorization code interception.",[25,104,106,109,112,115,129,131,139,142,145],{"title":105},"Add PKCE Protection",[13,107,108],{},"Implement PKCE (Proof Key for Code Exchange) for OAuth.",[13,110,111],{},"PKCE prevents authorization code interception attacks.",[13,113,114],{},"Flow:",[46,116,117,120,123,126],{},[49,118,119],{},"Generate code_verifier: random 43-128 character string",[49,121,122],{},"Create code_challenge: base64url(sha256(code_verifier))",[49,124,125],{},"Send code_challenge in authorization request",[49,127,128],{},"Send code_verifier in token exchange",[13,130,63],{},[85,132,133,136],{},[49,134,135],{},"code_verifier = crypto.randomBytes(32).toString('base64url')",[49,137,138],{},"code_challenge = base64url(sha256(code_verifier))",[13,140,141],{},"Authorization URL:\n&code_challenge={challenge}\n&code_challenge_method=S256",[13,143,144],{},"Token request:\ncode_verifier={verifier}",[13,146,147],{},"Store code_verifier in session alongside state.\nBoth must be present and valid on callback.",[149,150,151],"warning-box",{},[13,152,153,157],{},[154,155,156],"strong",{},"Never skip the state parameter:"," Without state verification, attackers can use CSRF to log users into attacker-controlled accounts or steal authorization codes.",[17,159,161],{"id":160},"token-handling","Token Handling",[13,163,164],{},"Paste this prompt to set up secure storage for OAuth access tokens, refresh tokens, and ID tokens. Your AI will generate encrypted storage patterns for server-side apps and Backend-for-Frontend (BFF) patterns for SPAs, keeping tokens out of the browser.",[25,166,168,171,174,185,188,202,205,216,219],{"title":167},"Secure Token Storage",[13,169,170],{},"Handle OAuth tokens securely after authentication.",[13,172,173],{},"After token exchange, you receive:",[85,175,176,179,182],{},[49,177,178],{},"access_token: for API calls",[49,180,181],{},"refresh_token: for getting new access tokens",[49,183,184],{},"id_token: user identity (if OpenID Connect)",[13,186,187],{},"Storage rules:",[46,189,190,193,196,199],{},[49,191,192],{},"Never expose tokens to client/frontend",[49,194,195],{},"Store encrypted in database or secure session",[49,197,198],{},"access_token: short-lived, can be in memory",[49,200,201],{},"refresh_token: encrypt at rest, secure storage",[13,203,204],{},"For server-side apps:",[85,206,207,210,213],{},[49,208,209],{},"Store tokens in encrypted session",[49,211,212],{},"Use httpOnly cookies for session ID",[49,214,215],{},"Refresh tokens before they expire",[13,217,218],{},"For SPAs (avoid if possible):",[85,220,221,224,227],{},[49,222,223],{},"Use BFF (Backend for Frontend) pattern",[49,225,226],{},"Keep tokens server-side",[49,228,229],{},"Don't store tokens in localStorage",[17,231,233],{"id":232},"id-token-verification","ID Token Verification",[13,235,236],{},"Copy this prompt to generate proper ID token verification logic. Your AI will create signature validation against the provider's JWKS, claim checks (issuer, audience, expiration), and safe extraction of user identity fields.",[25,238,240,243,246,266,269,283,286,297],{"title":239},"Verify ID Tokens",[13,241,242],{},"Properly verify ID tokens from OAuth providers.",[13,244,245],{},"Never trust ID token claims without verification:",[46,247,248,251,254,257,260,263],{},[49,249,250],{},"Verify signature using provider's public keys",[49,252,253],{},"Check iss (issuer) matches expected provider",[49,255,256],{},"Check aud (audience) matches your client ID",[49,258,259],{},"Check exp (expiration) is in the future",[49,261,262],{},"Check iat (issued at) is reasonable",[49,264,265],{},"For Google: check azp if multiple clients",[13,267,268],{},"Fetch provider's JWKS (JSON Web Key Set):",[85,270,271,280],{},[49,272,273,274],{},"Google: ",[275,276,277],"a",{"href":277,"rel":278},"https://www.googleapis.com/oauth2/v3/certs",[279],"nofollow",[49,281,282],{},"Cache keys but refresh periodically",[13,284,285],{},"After verification:",[85,287,288,291,294],{},[49,289,290],{},"Extract sub (subject) as stable user ID",[49,292,293],{},"email may not be verified - check email_verified claim",[49,295,296],{},"Don't trust name/picture without sanitizing",[13,298,299],{},"Use libraries: jose, jsonwebtoken with verify options",[301,302,303],"tip-box",{},[13,304,305,308],{},[154,306,307],{},"Pro tip:"," Use established OAuth libraries like NextAuth.js, Passport, or Auth.js instead of implementing OAuth yourself. They handle the security details correctly.",[310,311,312,319],"faq-section",{},[313,314,316],"faq-item",{"question":315},"Should I use OAuth for my app?",[13,317,318],{},"OAuth (social login) is great for reducing friction and offloading password security. But you're trusting the provider, and users might not want to link accounts. Offer it alongside traditional login.",[313,320,322],{"question":321},"What's the difference between OAuth and OpenID Connect?",[13,323,324],{},"OAuth is for authorization (accessing resources). OpenID Connect adds authentication (identity) on top. When you need to know who the user is, you want OIDC which gives you an ID token.",[17,326,328],{"id":327},"further-reading","Further Reading",[13,330,331],{},"Want to understand the vulnerability before fixing it? These guides explain what's happening and why.",[85,333,334,340,346],{},[49,335,336],{},[275,337,339],{"href":338},"/blog/vulnerabilities/exposed-api-keys","Understanding exposed API keys",[49,341,342],{},[275,343,345],{"href":344},"/blog/how-to/hide-api-keys","How to hide API keys step-by-step",[49,347,348],{},[275,349,351],{"href":350},"/blog/best-practices/secrets","Secret management best practices",[353,354,355,361],"related-articles",{},[356,357],"related-card",{"description":358,"href":359,"title":360},"Token security","/blog/prompts/secure-jwt-implementation","Secure JWT Implementation",[356,362],{"description":363,"href":364,"title":365},"Complete login security","/blog/prompts/secure-login-flow","Secure Login Flow",[367,368,371,375],"cta-box",{"href":369,"label":370},"/","Start Free Scan",[17,372,374],{"id":373},"check-your-oauth-setup","Check Your OAuth Setup",[13,376,377],{},"Scan your OAuth implementation for security issues.",{"title":379,"searchDepth":380,"depth":380,"links":381},"",2,[382,383,384,385,386,387],{"id":19,"depth":380,"text":20},{"id":98,"depth":380,"text":99},{"id":160,"depth":380,"text":161},{"id":232,"depth":380,"text":233},{"id":327,"depth":380,"text":328},{"id":373,"depth":380,"text":374},"prompts","2026-02-12","2026-03-06","AI prompts to implement OAuth securely. Proper state parameter handling, token storage, and protection against common OAuth attacks.",false,"md",null,"cyan",{},true,"AI prompts to implement OAuth authentication securely.","/blog/prompts/add-oauth-security","[object Object]","BlogPosting",{"title":5,"description":391},{"loc":399},"blog/prompts/add-oauth-security",[406],"Authentication","summary_large_image","vrT_HQBw0pmgvtusx0bZ9F0Rp8tCbpHXAd_5wMXnmfc",1775843939060]