/lovable-issues

Adding OAuth Providers (Google, GitHub) in Lovable Auth Flow

Avoid OAuth pitfalls in Lovable. Learn to add login options and apply best practices with proper redirects for secure auth flows.

Book a free  consultation
4.9
Clutch rating 🌟
600+
Happy partners
17+
Countries served
190+
Team members
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

Book a free No-Code consultation

Why OAuth Setup Can Break Without Proper Redirects in Lovable

 

Direct answer

 

OAuth breaks in Lovable when the app's redirect_uri doesn't exactly match the URI registered with the OAuth provider. In Lovable this happens often because preview URLs are ephemeral (different host), you can accidentally hardcode a local URL, or the app uses a different scheme/path (missing trailing slash, http vs https). Providers reject the exchange when the redirect doesn't exactly match, producing redirect_mismatch or invalid\_grant errors.

 

Why this is the real problem (detailed)

 

  • Exact-match requirement: OAuth providers compare the incoming redirect\_uri to the list you registered. Any difference (host, port, scheme, path, trailing slash) causes failure.
  • Lovable preview vs publish: Lovable preview URLs are temporary and different from the published domain. If you register only your published URL, preview flows fail. If you register only preview, published app fails.
  • Hardcoded URIs in code: Code that sets redirect\_uri to localhost or a specific domain will break when running inside Lovable unless it reads the environment/secret you configured in Lovable.
  • HTTPS requirement: Many providers require HTTPS. Lovable preview/published URLs are HTTPS — but local dev (http://localhost) may be rejected if provider disallows it.
  • Fixing requires exact config in two places: your app (use environment-driven redirect URI) and the OAuth provider dashboard (add every redirect you will use: preview and production). Updating only one side leaves the flow broken.

 

Lovable prompts you can paste into the Lovable chat to fix it

 

Paste each prompt into Lovable chat so Lovable can edit code and guide you to set secrets and provider console entries.

 

// Prompt A: Replace hardcoded redirect with env-driven value
// Edit file: src/server/auth/oauth.ts (or the file where you create the OAuth redirect)
// Instruction to Lovable:
// 1) Open src/server/auth/oauth.ts
// 2) Replace any hardcoded redirect URI with process.env.OAUTH_REDIRECT
// 3) Export/return the redirectUri so callback handlers use it
//
// Provide the updated file content below and ensure it reads process.env.OAUTH_REDIRECT.

 

// Prompt B: Create README comment and environment secret names
// Edit file: README.md (project root) - add a short section "OAuth redirect setup for Lovable"
// Instruction to Lovable:
// 1) Append a section that tells developers to set these secrets in Lovable's Secrets UI:
//    - OAUTH_CLIENT_ID
//    - OAUTH_CLIENT_SECRET
//    - OAUTH_REDIRECT  (full absolute URL used by the provider, e.g., https://<preview-or-prod>/auth/callback)
// 2) Include a note that preview URLs change and both preview and published URLs must be added to the provider console.

 

// Prompt C: Secrets UI guidance for the user (action outside code but Lovable should show instructions)
// Instruction to Lovable:
// Show the user step-by-step how to open the Lovable Secrets panel and add:
//   - OAUTH_CLIENT_ID: (paste client id)
//   - OAUTH_CLIENT_SECRET: (paste client secret)
//   - OAUTH_REDIRECT: use the exact full callback URL for the environment they will test (copy from Preview or Published URL + /auth/callback)
// Also instruct user to add that same exact URL in their OAuth provider's Allowed Redirect URIs (this is outside Lovable: provider web dashboard).

 

Testing steps inside Lovable: After applying the code change and adding secrets, click Preview, copy the preview URL, confirm OAUTH\_REDIRECT matches that preview URL in both Lovable Secrets and your provider console, then test the sign-in flow. Publish after you add the published domain to the provider's redirect list.

Still stuck?
Copy this prompt into ChatGPT and get a clear, personalized explanation.

This prompt helps an AI assistant understand your setup and guide you through the fix step by step, without assuming technical knowledge.

AI AI Prompt

How to Add OAuth Login Options to Lovable Auth Flow

Yes — you can add OAuth providers by: adding provider buttons in the UI, storing provider client_id/client_secret in Lovable’s Secrets UI, creating server-side OAuth start and callback endpoints inside the Lovable app (so the secret never goes to the browser), and wiring the frontend to redirect to those endpoints. Use Preview to test and Publish (or GitHub export if you need terminal work). Below are Lovable-ready prompts you can paste into the project chat that instruct Lovable to implement the pieces (Next.js fallback provided; Lovable should adapt if your framework differs).

 

Prompts to paste into Lovable — create server endpoints and UI

 

  • Prompt A — Detect framework and add OAuth start / callback endpoints (Next.js fallback)

    Paste this into Lovable chat so it edits files:

    // Detect the app framework. If it's Next.js, create API routes.
    // If it's a different framework, implement equivalent server endpoints and tell me which files you changed.
    
    // For Next.js: create src/pages/api/auth/[provider].ts
    // This endpoint builds and redirects to the provider authorization URL using secrets.
    
    Create file src/pages/api/auth/[provider].ts with this content:
    
    // Start OAuth flow: redirect to provider's auth URL
    import { NextApiRequest, NextApiResponse } from 'next'
    
    export default async function handler(req: NextApiRequest, res: NextApiResponse) {
      const { provider } = req.query
      // // Add providers here. Example: google
      if (provider !== 'google') {
        return res.status(400).send('unsupported provider')
      }
      const clientId = process.env.OAUTH_GOOGLE_CLIENT_ID
      const redirectUri = process.env.OAUTH_REDIRECT_URI // set in Lovable Secrets
      const scope = encodeURIComponent('openid email profile')
      const authUrl = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code&scope=${scope}&access_type=offline&prompt=consent`
      return res.redirect(authUrl)
    }
    
    
    // For Next.js: create src/pages/api/auth/callback.ts
    // This endpoint exchanges code for tokens server-side and returns a short-lived session cookie or JSON.
    
    Create file src/pages/api/auth/callback.ts with this content:
    
    // OAuth callback: exchange code for tokens securely
    import { NextApiRequest, NextApiResponse } from 'next'
    import fetch from 'node-fetch' // Lovable will add dependency if needed via GitHub export; otherwise use global fetch if available
    
    export default async function handler(req: NextApiRequest, res: NextApiResponse) {
      const { code, provider } = req.query
      if (!code || provider !== 'google') return res.status(400).send('missing code or provider')
    
      const tokenRes = await fetch('https://oauth2.googleapis.com/token', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: new URLSearchParams({
          code: String(code),
          client_id: String(process.env.OAUTH_GOOGLE_CLIENT_ID),
          client_secret: String(process.env.OAUTH_GOOGLE_CLIENT_SECRET),
          redirect_uri: String(process.env.OAUTH_REDIRECT_URI),
          grant_type: 'authorization_code'
        })
      })
    
      const tokenJson = await tokenRes.json()
      // // At this point, create a session for the user and set a secure cookie (or return token to client)
      // // For demo: return token JSON (in production create a server session)
      return res.status(200).json(tokenJson)
    }
    
  • Prompt B — Add OAuth buttons and wire to start endpoint

    Paste this into Lovable chat so it creates/updates UI files:

    // Create a simple React component for OAuth buttons and mount it on the existing login page.
    // Create file src/components/OAuthButtons.tsx
    
    Create file src/components/OAuthButtons.tsx with this content:
    
    import React from 'react'
    
    export default function OAuthButtons() {
      // // Replace or extend providers as implemented server-side
      const providers = ['google']
    
      return (
        <div>
          {providers.map((p) => (
            // // clicking triggers redirect to our server start endpoint
            <button key={p} onClick={() => { window.location.href = `/api/auth/${p}` }}>
              Continue with {p[0].toUpperCase() + p.slice(1)}
            </button>
          ))}
        </div>
      )
    }
    
     // Update your login page to import and render this component.
     // If your login page is src/pages/login.tsx or src/pages/index.tsx, insert inside the auth area:
     // import OAuthButtons from 'src/components/OAuthButtons'
     // <OAuthButtons />
    
  • Prompt C — Add provider secrets via Lovable Secrets UI (instructions for you)

    Paste this into Lovable chat to add guidance and ensure code uses these names:

    // Add the following secrets in Lovable Cloud -> Secrets (use exact names):
    // OAUTH_GOOGLE_CLIENT_ID
    // OAUTH_GOOGLE_CLIENT_SECRET
    // OAUTH_REDIRECT_URI
    
    // Set OAUTH_REDIRECT_URI to your app's published callback URL, e.g.:
    // https://your-published-domain.com/api/auth/callback
    // // For Preview testing, you can temporarily set it to the Preview URL + /api/auth/callback.
    // // Make sure the provider console (Google) has the exact same redirect URI registered.
    
  • Prompt D — Test in Preview and Publish (or use GitHub export for extra dependencies)

    Paste this into Lovable chat:

    // Use Preview to test the flow: click "Continue with Google" in the previewed login page.
    // After verifying, Publish the app and update provider console redirect URI to the published domain (if you used preview earlier).
    
    // If node-fetch or another dependency is flagged and you'd rather install it locally, export to GitHub and run npm/yarn install & deploy outside Lovable. Label that step "outside Lovable (terminal required)".
    

 

What to watch for

 

  • Never put client\_secret in front-end — store it in Lovable Secrets and use only server endpoints to exchange codes.
  • Redirect URI must match provider console — update it after Publish; you can use Preview to iterate but switch to published URL before final testing.

 

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Book a Free Consultation

Best Practices for Using OAuth in Lovable Authentication Flows

Store secrets in Lovable Secrets, do all token exchanges and validation on the server side, use PKCE + state for client-side flows, keep scopes minimal, set HttpOnly Secure SameSite cookies and rotate refresh tokens, never log secrets, and test in Preview before exporting to GitHub if you need terminal-only changes.

 

Secrets & Configuration (Lovable Secrets UI)

 

Best practice: Put OAuth client IDs, client secrets, and an encryption key only in Lovable’s Secrets UI — never in source files. Reference them via process.env in server code.

  • Lovable prompt: Create/update these secrets in Secrets UI: OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, TOKEN_ENCRYPTION_KEY, OAUTH_PROVIDER_JWKS\_URL.
  • Lovable prompt: Create file src/server/config.ts that reads these env vars and exports them for server code.

 

// Create src/server/config.ts
// // Read secrets from process.env (Lovable injects Secrets into process.env)
export const OAUTH_CLIENT_ID = process.env.OAUTH_CLIENT_ID!
export const OAUTH_CLIENT_SECRET = process.env.OAUTH_CLIENT_SECRET!
export const TOKEN_ENCRYPTION_KEY = process.env.TOKEN_ENCRYPTION_KEY!
export const OAUTH_PROVIDER_JWKS_URL = process.env.OAUTH_PROVIDER_JWKS_URL!

 

PKCE + State (client-side helpers stored in project)

 

Best practice: Generate PKCE code_verifier & code_challenge on the client and use a cryptographically-random state. Store only the state in a short-lived HttpOnly cookie performed by server helper endpoints; do the real token exchange server-side.

  • Lovable prompt: Add src/utils/pkce.ts with functions to generate a code_verifier/code_challenge and generate a secure random state (for client usage and server validation).

 

// Create src/utils/pkce.ts
// // helper functions for PKCE and state generation
export function generateCodeVerifier(){ /* // implement secure random base64-url string */ }
export function generateCodeChallenge(verifier){ /* // implement SHA256 then base64-url */ }
export function generateState(){ /* // secure random string */ }

 

Server-side Token Exchange & Validation

 

Best practice: Implement server API routes that perform code -> token exchange, validate ID tokens (via JWKS if OIDC), fetch userinfo server-side, and persist only encrypted tokens or session IDs.

  • Lovable prompt: Create src/server/api/oauth/callback.ts that:
    • Reads state from a signed HttpOnly cookie and compares it.
    • Performs token exchange using OAUTH_CLIENT_ID/OAUTH_CLIENT_SECRET.
    • Validates id_token signature using OAUTH_PROVIDER_JWKS_URL.
    • Encrypts tokens with TOKEN_ENCRYPTION_KEY and stores them in src/server/sessionStore.ts (file-based/simple KV for Preview; swap to DB in prod).

 

// Create src/server/api/oauth/callback.ts
// // validate state cookie, exchange code for tokens, validate ID token via JWKS,
// // encrypt tokens with TOKEN_ENCRYPTION_KEY and create a server session

 

Cookies, Sessions & Cookie Flags

 

Best practice: Use HttpOnly, Secure, SameSite=strict cookies for session IDs; set short lifetimes for access tokens, rotate refresh tokens, and rotate session IDs on privilege changes.

  • Lovable prompt: Create src/server/session.ts to issue HttpOnly Secure SameSite cookies and to rotate session IDs. Use TOKEN_ENCRYPTION_KEY to encrypt token blobs stored server-side instead of sending tokens to the client.

 

// Create src/server/session.ts
// // setCookie(response, { httpOnly: true, secure: true, sameSite: 'strict', maxAge: ... })
// // rotateSession(response, oldSessionId) -> newSessionId

 

Scopes, Least Privilege & Refresh Token Handling

 

Best practice: Request the minimal scopes needed, prefer short-lived access tokens, implement refresh-token rotation server-side, and revoke old refresh tokens after use.

  • Lovable prompt: Update src/server/config.ts scopes list and add a server-side refresh endpoint src/server/api/oauth/refresh.ts that exchanges and rotates refresh tokens and updates encrypted store entries.

 

// Create src/server/api/oauth/refresh.ts
// // read encrypted refresh token, call provider token endpoint to refresh,
// // replace stored token with new encrypted token, revoke old refresh token if provider supports it

 

Error Handling, Logging & Monitoring

 

Best practice: Never log client secrets, tokens, or raw authorization codes. Log only correlation IDs and non-secret error codes. Capture and surface user-facing errors gracefully.

  • Lovable prompt: Add src/server/logging.ts helper that redacts tokens and ensures logs never include process.env values. Update OAuth endpoints to use that helper.

 

// Create src/server/logging.ts
// // function safeLog(ctx, message, meta) { // redact token-like keys in meta before logging }

 

Preview, Publish & GitHub Export

 

Best practice: Test OAuth flows in Lovable Preview using Secrets UI values. When you need to run migrations, add provider configuration that requires terminal/infra changes, export/sync to GitHub and make those infra changes outside Lovable (outside Lovable — terminal required).

  • Lovable prompt: After implementing the above files, Preview the app and exercise an OAuth sign-in path. If you must change provider-side settings or run DB migrations, sync to GitHub and handle those steps outside Lovable.

 


Recognized by the best

Trusted by 600+ businesses globally

From startups to enterprises and everything in between, see for yourself our incredible impact.

RapidDev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with.

They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

Arkady
CPO, Praction
Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost.

He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Donald Muir
Co-Founder, Arc
RapidDev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space.

They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Mat Westergreen-Thorne
Co-CEO, Grantify
RapidDev is an excellent developer for custom-code solutions.

We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Emmanuel Brown
Co-Founder, Church Real Estate Marketplace
Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 

This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Samantha Fekete
Production Manager, Media Production Company
The pSEO strategy executed by RapidDev is clearly driving meaningful results.

Working with RapidDev has delivered measurable, year-over-year growth. Comparing the same period, clicks increased by 129%, impressions grew by 196%, and average position improved by 14.6%. Most importantly, qualified contact form submissions rose 350%, excluding spam.

Appreciation as well to Matt Graham for championing the collaboration!

Michael W. Hammond
Principal Owner, OCD Tech

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We’ll discuss your project and provide a custom quote at no cost.