Loading...
Loading...
> Enable one-click Google sign-in for your users with OAuth 2.0 integration.
Fabrk supports Google OAuth through NextAuth v5 with one-click sign-in with Google accounts, automatic account linking for existing email users, profile photo and name sync from Google, conditional enabling based on environment variables, and secure token handling with JWT sessions.
DESC: Go to Google Cloud Console, create a new project, navigate to APIs & Services → OAuth consent screen, configure with User type: External, your app name, support email, and authorized domains. Add scopes: email, profile, openid.
DESC: Go to APIs & Services → Credentials, click Create Credentials → OAuth client ID, select Web application. Add Authorized JavaScript origins (http://localhost:3000 for dev, https://yourdomain.com for prod). Add Authorized redirect URIs: http://localhost:3000/api/auth/callback/google and https://yourdomain.com/api/auth/callback/google. Copy the Client ID and Client Secret.
DESC: Add to .env.local. Google OAuth is automatically enabled when these variables are set.
1$GOOGLE_CLIENT_ID="xxxxxxxxxxxx.apps.googleusercontent.com"2$GOOGLE_CLIENT_SECRET="GOCSPX-xxxxxxxxxxxx"
Google provider is configured in src/lib/auth.ts
1// src/lib/auth.ts2import NextAuth from "next-auth";3import Google from "next-auth/providers/google";4import { env } from "@/lib/env";56export const { handlers, auth, signIn, signOut } = NextAuth({7 providers: [8 // Only include Google if credentials are set9 ...(env.server.GOOGLE_CLIENT_ID && env.server.GOOGLE_CLIENT_SECRET10 ? [11 Google({12 clientId: env.server.GOOGLE_CLIENT_ID,13 clientSecret: env.server.GOOGLE_CLIENT_SECRET,14 }),15 ]16 : []),17 // ... other providers18 ],19 callbacks: {20 async signIn({ user, account }) {21 if (account?.provider === "google") {22 // Check if user exists with this email23 const existingUser = await prisma.user.findUnique({24 where: { email: user.email },25 });2627 if (existingUser) {28 // Link Google account to existing user29 await prisma.account.upsert({30 where: {31 provider_providerAccountId: {32 provider: "google",33 providerAccountId: account.providerAccountId,34 },35 },36 update: {},37 create: {38 userId: existingUser.id,39 type: account.type,40 provider: account.provider,41 providerAccountId: account.providerAccountId,42 access_token: account.access_token,43 refresh_token: account.refresh_token,44 },45 });46 }47 }48 return true;49 },50 },51});
Add Google sign-in to your login page
1"use client";23import { signIn } from "next-auth/react";4import { Button } from "@/components/ui/button";56export function GoogleSignInButton() {7 return (8 <Button9 variant="outline"10 className="w-full"11 onClick={() => signIn("google", { callbackUrl: "/dashboard" })}12 >13 <svg className="mr-2 h-4 w-4" viewBox="0 0 24 24">14 <path15 d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"16 fill="#4285F4"17 />18 <path19 d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"20 fill="#34A853"21 />22 <path23 d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"24 fill="#FBBC05"25 />26 <path27 d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"28 fill="#EA4335"29 />30 </svg>31 Continue with Google32 </Button>33 );34}
Show Google button only when configured
1import { config } from "@/config";23export function LoginForm() {4 return (5 <div>6 {/* Email/password form */}7 <form>...</form>89 {config.features.googleAuth && (10 <>11 <div className="relative my-4">12 <div className="absolute inset-0 flex items-center">13 <span className="w-full border-t" />14 </div>15 <div className="relative flex justify-center text-xs uppercase">16 <span className="bg-background px-2 text-muted-foreground">17 Or continue with18 </span>19 </div>20 </div>21 <GoogleSignInButton />22 </>23 )}24 </div>25 );26}
Error: redirect_uri_mismatch
The callback URL doesn't match what's configured in Google Cloud Console. Ensure your redirect URI exactly matches, including protocol (http vs https).
Error: access_denied
User denied access or app is in testing mode with unverified users. Add test users in OAuth consent screen or publish the app.
Button not appearing
Check that GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET are set. Restart the dev server after adding env vars.
PROTECT YOUR OAUTH CLIENT SECRET
CRITICAL: The GOOGLE_CLIENT_SECRET grants access to your OAuth application. Leaking it allows attackers to impersonate your app and access user data.
Safe to expose: GOOGLE_CLIENT_ID is public and safe for client-side use. Only the CLIENT_SECRET must be protected.