QR

qruiq-google-auth

Automates Google OAuth integration, database setup with Prisma, and middleware protection for Next.js applications.

Install

mkdir -p .claude/skills/qruiq-google-auth && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/13164" && unzip -o skill.zip -d .claude/skills/qruiq-google-auth && rm skill.zip

Installs to .claude/skills/qruiq-google-auth

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Add Google OAuth login to a Next.js app using NextAuth.js v4 + PrismaAdapter + JWT sessions. Use when asked to "add Google login", "add auth", "add authentication", or "setup NextAuth".
185 chars✓ has a “when” trigger
Intermediate

Key capabilities

  • Install NextAuth.js and Prisma dependencies
  • Copy template API routes and middleware
  • Initialize Prisma and add NextAuth tables
  • Generate NEXTAUTH_SECRET and configure environment variables
  • Integrate SessionProvider into the Next.js app
  • Protect routes using Next.js middleware

How it works

The skill installs required packages, copies authentication and middleware files, initializes Prisma with NextAuth tables, and sets up environment variables for Google OAuth and JWT sessions.

Inputs & outputs

You give it
Google OAuth Client ID, Google OAuth Client Secret, Prisma database connection string, App external URL
You get back
Next.js application with Google OAuth login, Prisma schema configured for NextAuth, and route protection middleware

When to use qruiq-google-auth

  • Add Google authentication to Next.js
  • Setup NextAuth with Prisma
  • Protect routes with middleware

About this skill

qruiq-google-auth

NextAuth.js v4 + PrismaAdapter + Google OAuth + JWT Session + route protection middleware.

Parameters

Collect before execution:

ParameterRequiredDescriptionExample
GOOGLE_CLIENT_IDYesGoogle OAuth Client IDxxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRETYesGoogle OAuth Client SecretGOCSPX-xxx
DATABASE_URLYesPrisma database connection stringmysql://user:pass@host:3306/db
NEXTAUTH_URLYesApp external URL (with scheme)https://my-app.qruiq.app

NEXTAUTH_SECRET is auto-generated during setup.

Steps

Execute all steps directly. Do not list as TODOs.

1. Install dependencies

yarn add next-auth @auth/prisma-adapter @prisma/client
yarn add -D prisma

2. Copy template files

cp -r ~/.qruiq/skills/skills/qruiq-google-auth/template/app/api/auth app/api/
cp -r ~/.qruiq/skills/skills/qruiq-google-auth/template/app/api/health app/api/
cp ~/.qruiq/skills/skills/qruiq-google-auth/template/middleware.ts .

3. Initialize Prisma

npx prisma init

Edit prisma/schema.prisma — add the four NextAuth tables (Account, Session, User, VerificationToken). See "Prisma Schema" section below.

npx prisma db push

4. Create .env

NEXTAUTH_SECRET=<run: openssl rand -base64 32>
NEXTAUTH_URL=<NEXTAUTH_URL>
GOOGLE_CLIENT_ID=<GOOGLE_CLIENT_ID>
GOOGLE_CLIENT_SECRET=<GOOGLE_CLIENT_SECRET>
DATABASE_URL=<DATABASE_URL>

5. Add SessionProvider to app/providers.tsx

import { SessionProvider } from "next-auth/react";

export function Providers({ children, themeProps, session }) {
  const router = useRouter();
  return (
    <SessionProvider session={session}>
      <HeroUIProvider navigate={router.push}>
        <NextThemesProvider {...themeProps}>{children}</NextThemesProvider>
      </HeroUIProvider>
    </SessionProvider>
  );
}

Core files

app/api/auth/[...nextauth]/lib/options.ts

import { PrismaAdapter } from '@auth/prisma-adapter';
import type { NextAuthOptions } from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';
import prisma from '@/lib/prisma';

export const authOptions: NextAuthOptions = {
  secret: process.env.NEXTAUTH_SECRET,
  adapter: PrismaAdapter(prisma),
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID ?? '',
      clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? '',
      authorization: {
        params: {
          prompt: 'consent',
          access_type: 'offline',
          response_type: 'code',
          redirect_uri: `${process.env.NEXTAUTH_URL}/api/auth/callback/google`,
        },
      },
      checks: ['state', 'pkce'],
      profile(profile) {
        return {
          id: profile.sub,
          name: profile.name,
          email: profile.email,
          image: profile.picture,
          emailVerified: profile.email_verified,
        };
      },
    }),
  ],
  pages: { signIn: '/', error: '/' },
  session: { strategy: 'jwt', maxAge: 30 * 24 * 60 * 60 },
  callbacks: {
    async jwt({ token, user, account }) {
      if (user) token.sub = user.id;
      if (account) token.provider = account.provider;
      return token;
    },
    async session({ session, token }) {
      if (session.user) session.user.id = token.sub as string;
      return session;
    },
    async redirect({ url, baseUrl }) {
      if (url.startsWith('/')) return new URL(url, baseUrl).toString();
      if (url.startsWith(baseUrl)) return url;
      return baseUrl;
    },
  },
};

middleware.ts — Route protection

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { getToken } from 'next-auth/jwt';

const PUBLIC_PATHS = ['/', '/api/auth'];

export async function middleware(request: NextRequest) {
  const path = request.nextUrl.pathname;
  if (path.startsWith('/api/auth/callback/')) return NextResponse.next();
  const isPublic = PUBLIC_PATHS.some(p => path === p || path.startsWith(p + '/'));
  if (isPublic || path.startsWith('/api/')) return NextResponse.next();
  const token = await getToken({ req: request, secret: process.env.NEXTAUTH_SECRET });
  if (token) return NextResponse.next();
  const callbackUrl = encodeURIComponent(request.url);
  return NextResponse.redirect(new URL(`/?callbackUrl=${callbackUrl}`, request.url));
}

export const config = {
  matcher: ['/dashboard/:path*', '/profile/:path*'],
};

Prisma Schema

model Account {
  id                String  @id @default(cuid())
  userId            String
  type              String
  provider          String
  providerAccountId String
  refresh_token     String? @db.Text
  access_token      String? @db.Text
  expires_at        Int?
  token_type        String?
  scope             String?
  id_token          String? @db.Text
  session_state     String?
  user              User    @relation(fields: [userId], references: [id], onDelete: Cascade)
  @@unique([provider, providerAccountId])
}

model Session {
  id           String   @id @default(cuid())
  sessionToken String   @unique
  userId       String
  expires      DateTime
  user         User     @relation(fields: [userId], references: [id], onDelete: Cascade)
}

model User {
  id            String    @id @default(cuid())
  name          String?
  email         String?   @unique
  emailVerified DateTime?
  image         String?
  accounts      Account[]
  sessions      Session[]
}

model VerificationToken {
  identifier String
  token      String   @unique
  expires    DateTime
  @@unique([identifier, token])
}

Google Cloud Console setup

  1. Go to Google Cloud Console → APIs & Services → Credentials
  2. Create OAuth 2.0 Client ID (Web application)
  3. Authorized JavaScript origins: http://localhost:3000 + https://your-domain.com
  4. Authorized redirect URIs: http://localhost:3000/api/auth/callback/google + https://your-domain.com/api/auth/callback/google

Notes

  • NEXTAUTH_URL must be injected via K8s Secret when deploying — must match external domain exactly
  • Google Console callback URL must exactly match NEXTAUTH_URL, otherwise redirect_uri_mismatch
  • checks: ['state', 'pkce'] is a security best practice — do not remove
  • Multiple domains (dev/prod) each need separate entries in Google Console

When not to use it

  • When not using Next.js for the application
  • When not using Prisma for the database adapter
  • When not using Google as the OAuth provider

Limitations

  • Requires a Next.js application
  • Requires Prisma as the database adapter
  • Limited to Google as the OAuth provider

How it compares

This skill automates the setup of Google OAuth with NextAuth.js and Prisma, including file copying, dependency installation, and environment configuration, which would otherwise require manual configuration of multiple components.

Compared to similar skills

qruiq-google-auth side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
qruiq-google-auth (this skill)04moReviewIntermediate
drizzle-orm322moNo flagsIntermediate
event-store-design52moNo flagsAdvanced
springboot-patterns115moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry