Google Antigravity Directory

The #1 directory for Google Antigravity prompts, rules, workflows & MCP servers. Optimized for Gemini 3 agentic development.

Resources

PromptsMCP ServersAntigravity RulesGEMINI.md GuideBest Practices

Company

Submit PromptAntigravityAI.directory

Popular Prompts

Next.js 14 App RouterReact TypeScriptTypeScript AdvancedFastAPI GuideDocker Best Practices

Legal

Privacy PolicyTerms of ServiceContact Us
Featured on FazierVerified on Verified ToolsFeatured on WayfindioAntigravity AI - Featured on Startup FameFeatured on Wired BusinessFeatured on Twelve ToolsListed on Turbo0Featured on findly.toolsFeatured on Aura++That App ShowFeatured on FazierVerified on Verified ToolsFeatured on WayfindioAntigravity AI - Featured on Startup FameFeatured on Wired BusinessFeatured on Twelve ToolsListed on Turbo0Featured on findly.toolsFeatured on Aura++That App Show

© 2026 Antigravity AI Directory. All rights reserved.

The #1 directory for Google Antigravity IDE

This website is not affiliated with, endorsed by, or associated with Google LLC. "Google" and "Gemini" are trademarks of Google LLC.

Antigravity AI Directory
PromptsMCPBest PracticesUse CasesLearn
Home
Prompts
JWT Authentication Complete Guide

JWT Authentication Complete Guide

Implement secure JWT authentication with refresh tokens and best practices

AuthJWTSecurityBackend
by Community
⭐0Stars
👁️9Views
.antigravity
# JWT Authentication Complete Guide for Google Antigravity

Implement secure JWT authentication in your Google Antigravity projects. This guide covers token generation, validation, refresh tokens, and security best practices.

## JWT Token Service

Create a secure token management service:

```typescript
// src/lib/auth/jwt.ts
import { SignJWT, jwtVerify, JWTPayload } from "jose";
import { cookies } from "next/headers";

interface TokenPayload extends JWTPayload {
  userId: string;
  email: string;
  role: "user" | "admin";
  sessionId: string;
}

interface TokenPair {
  accessToken: string;
  refreshToken: string;
}

const ACCESS_TOKEN_SECRET = new TextEncoder().encode(process.env.JWT_ACCESS_SECRET);
const REFRESH_TOKEN_SECRET = new TextEncoder().encode(process.env.JWT_REFRESH_SECRET);

const ACCESS_TOKEN_EXPIRY = "15m";
const REFRESH_TOKEN_EXPIRY = "7d";

export async function generateTokenPair(payload: Omit<TokenPayload, "iat" | "exp" | "jti">): Promise<TokenPair> {
  const sessionId = crypto.randomUUID();
  const tokenPayload = { ...payload, sessionId };
  
  const accessToken = await new SignJWT(tokenPayload)
    .setProtectedHeader({ alg: "HS256", typ: "JWT" })
    .setIssuedAt()
    .setExpirationTime(ACCESS_TOKEN_EXPIRY)
    .setJti(crypto.randomUUID())
    .sign(ACCESS_TOKEN_SECRET);
  
  const refreshToken = await new SignJWT({ sessionId, userId: payload.userId })
    .setProtectedHeader({ alg: "HS256", typ: "JWT" })
    .setIssuedAt()
    .setExpirationTime(REFRESH_TOKEN_EXPIRY)
    .setJti(crypto.randomUUID())
    .sign(REFRESH_TOKEN_SECRET);
  
  // Store refresh token in database
  await storeRefreshToken(sessionId, payload.userId, refreshToken);
  
  return { accessToken, refreshToken };
}

export async function verifyAccessToken(token: string): Promise<TokenPayload | null> {
  try {
    const { payload } = await jwtVerify(token, ACCESS_TOKEN_SECRET);
    return payload as TokenPayload;
  } catch (error) {
    if (error instanceof Error && error.name === "JWTExpired") {
      console.log("Access token expired");
    }
    return null;
  }
}

export async function verifyRefreshToken(token: string): Promise<{ sessionId: string; userId: string } | null> {
  try {
    const { payload } = await jwtVerify(token, REFRESH_TOKEN_SECRET);
    
    // Check if refresh token is still valid in database
    const isValid = await validateStoredRefreshToken(
      payload.sessionId as string,
      token
    );
    
    if (!isValid) {
      return null;
    }
    
    return {
      sessionId: payload.sessionId as string,
      userId: payload.userId as string,
    };
  } catch {
    return null;
  }
}

export async function refreshAccessToken(refreshToken: string): Promise<TokenPair | null> {
  const tokenData = await verifyRefreshToken(refreshToken);
  
  if (!tokenData) {
    return null;
  }
  
  // Get user data from database
  const user = await getUserById(tokenData.userId);
  
  if (!user) {
    await revokeRefreshToken(tokenData.sessionId);
    return null;
  }
  
  // Revoke old refresh token (rotation)
  await revokeRefreshToken(tokenData.sessionId);
  
  // Generate new token pair
  return generateTokenPair({
    userId: user.id,
    email: user.email,
    role: user.role,
    sessionId: tokenData.sessionId,
  });
}
```

## Authentication Middleware

Protect routes with JWT validation:

```typescript
// src/middleware.ts
import { NextRequest, NextResponse } from "next/server";
import { verifyAccessToken, refreshAccessToken } from "@/lib/auth/jwt";

const PUBLIC_PATHS = ["/", "/login", "/signup", "/api/auth/login", "/api/auth/signup"];
const AUTH_PATHS = ["/login", "/signup"];

export async function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;
  
  // Skip public paths
  if (PUBLIC_PATHS.some((path) => pathname === path || pathname.startsWith("/api/public"))) {
    return NextResponse.next();
  }
  
  const accessToken = request.cookies.get("access_token")?.value;
  const refreshToken = request.cookies.get("refresh_token")?.value;
  
  // No tokens - redirect to login
  if (!accessToken && !refreshToken) {
    if (pathname.startsWith("/api")) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }
    return NextResponse.redirect(new URL("/login", request.url));
  }
  
  // Try to verify access token
  let user = accessToken ? await verifyAccessToken(accessToken) : null;
  
  // If access token invalid, try refresh
  if (!user && refreshToken) {
    const newTokens = await refreshAccessToken(refreshToken);
    
    if (newTokens) {
      user = await verifyAccessToken(newTokens.accessToken);
      
      if (user) {
        const response = NextResponse.next();
        
        // Set new tokens in cookies
        response.cookies.set("access_token", newTokens.accessToken, {
          httpOnly: true,
          secure: process.env.NODE_ENV === "production",
          sameSite: "lax",
          maxAge: 60 * 15, // 15 minutes
        });
        
        response.cookies.set("refresh_token", newTokens.refreshToken, {
          httpOnly: true,
          secure: process.env.NODE_ENV === "production",
          sameSite: "lax",
          maxAge: 60 * 60 * 24 * 7, // 7 days
        });
        
        return response;
      }
    }
  }
  
  // Still no valid user - clear cookies and redirect
  if (!user) {
    const response = pathname.startsWith("/api")
      ? NextResponse.json({ error: "Unauthorized" }, { status: 401 })
      : NextResponse.redirect(new URL("/login", request.url));
    
    response.cookies.delete("access_token");
    response.cookies.delete("refresh_token");
    
    return response;
  }
  
  // Redirect authenticated users away from auth pages
  if (AUTH_PATHS.some((path) => pathname.startsWith(path))) {
    return NextResponse.redirect(new URL("/dashboard", request.url));
  }
  
  // Add user info to headers for API routes
  const response = NextResponse.next();
  response.headers.set("x-user-id", user.userId);
  response.headers.set("x-user-role", user.role);
  
  return response;
}

export const config = {
  matcher: ["/((?!_next/static|_next/image|favicon.ico|public).*)"],
};
```

## Login API Route

Implement secure login endpoint:

```typescript
// src/app/api/auth/login/route.ts
import { NextRequest, NextResponse } from "next/server";
import { z } from "zod";
import bcrypt from "bcryptjs";
import { generateTokenPair } from "@/lib/auth/jwt";
import { getUserByEmail } from "@/lib/db/users";
import { withErrorHandler } from "@/lib/api/errorHandler";

const loginSchema = z.object({
  email: z.string().email(),
  password: z.string().min(8),
  rememberMe: z.boolean().optional(),
});

export const POST = withErrorHandler(async (request: NextRequest) => {
  const body = await request.json();
  const { email, password, rememberMe } = loginSchema.parse(body);
  
  // Get user from database
  const user = await getUserByEmail(email);
  
  if (!user) {
    // Use same error for security (prevent email enumeration)
    return NextResponse.json(
      { error: "Invalid credentials" },
      { status: 401 }
    );
  }
  
  // Verify password
  const isValidPassword = await bcrypt.compare(password, user.passwordHash);
  
  if (!isValidPassword) {
    // Log failed attempt for rate limiting
    await logFailedLoginAttempt(email);
    
    return NextResponse.json(
      { error: "Invalid credentials" },
      { status: 401 }
    );
  }
  
  // Check if account is locked
  if (user.lockedUntil && new Date(user.lockedUntil) > new Date()) {
    return NextResponse.json(
      { error: "Account is temporarily locked. Please try again later." },
      { status: 423 }
    );
  }
  
  // Generate tokens
  const tokens = await generateTokenPair({
    userId: user.id,
    email: user.email,
    role: user.role,
    sessionId: crypto.randomUUID(),
  });
  
  // Clear failed attempts
  await clearFailedLoginAttempts(email);
  
  const response = NextResponse.json({
    user: {
      id: user.id,
      email: user.email,
      name: user.name,
      role: user.role,
    },
  });
  
  // Set cookies
  const cookieOptions = {
    httpOnly: true,
    secure: process.env.NODE_ENV === "production",
    sameSite: "lax" as const,
  };
  
  response.cookies.set("access_token", tokens.accessToken, {
    ...cookieOptions,
    maxAge: 60 * 15,
  });
  
  response.cookies.set("refresh_token", tokens.refreshToken, {
    ...cookieOptions,
    maxAge: rememberMe ? 60 * 60 * 24 * 30 : 60 * 60 * 24 * 7,
  });
  
  return response;
});
```

## Client-Side Auth Hook

Create a React hook for authentication:

```typescript
// src/hooks/useAuth.ts
"use client";

import { useState, useEffect, useCallback } from "react";
import { useRouter } from "next/navigation";

interface User {
  id: string;
  email: string;
  name: string;
  role: "user" | "admin";
}

export function useAuth() {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  const router = useRouter();
  
  useEffect(() => {
    checkAuth();
  }, []);
  
  const checkAuth = async () => {
    try {
      const response = await fetch("/api/auth/me");
      if (response.ok) {
        const data = await response.json();
        setUser(data.user);
      }
    } catch (error) {
      console.error("Auth check failed:", error);
    } finally {
      setLoading(false);
    }
  };
  
  const login = useCallback(async (email: string, password: string) => {
    const response = await fetch("/api/auth/login", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ email, password }),
    });
    
    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.error || "Login failed");
    }
    
    const data = await response.json();
    setUser(data.user);
    router.push("/dashboard");
  }, [router]);
  
  const logout = useCallback(async () => {
    await fetch("/api/auth/logout", { method: "POST" });
    setUser(null);
    router.push("/login");
  }, [router]);
  
  return { user, loading, login, logout, checkAuth };
}
```

Google Antigravity generates secure JWT authentication implementations with proper token rotation, refresh token handling, and security best practices.

When to Use This Prompt

This Auth prompt is ideal for developers working on:

  • Auth applications requiring modern best practices and optimal performance
  • Projects that need production-ready Auth code with proper error handling
  • Teams looking to standardize their auth development workflow
  • Developers wanting to learn industry-standard Auth patterns and techniques

By using this prompt, you can save hours of manual coding and ensure best practices are followed from the start. It's particularly valuable for teams looking to maintain consistency across their auth implementations.

How to Use

  1. Copy the prompt - Click the copy button above to copy the entire prompt to your clipboard
  2. Paste into your AI assistant - Use with Claude, ChatGPT, Cursor, or any AI coding tool
  3. Customize as needed - Adjust the prompt based on your specific requirements
  4. Review the output - Always review generated code for security and correctness
💡 Pro Tip: For best results, provide context about your project structure and any specific constraints or preferences you have.

Best Practices

  • ✓ Always review generated code for security vulnerabilities before deploying
  • ✓ Test the Auth code in a development environment first
  • ✓ Customize the prompt output to match your project's coding standards
  • ✓ Keep your AI assistant's context window in mind for complex requirements
  • ✓ Version control your prompts alongside your code for reproducibility

Frequently Asked Questions

Can I use this Auth prompt commercially?

Yes! All prompts on Antigravity AI Directory are free to use for both personal and commercial projects. No attribution required, though it's always appreciated.

Which AI assistants work best with this prompt?

This prompt works excellently with Claude, ChatGPT, Cursor, GitHub Copilot, and other modern AI coding assistants. For best results, use models with large context windows.

How do I customize this prompt for my specific needs?

You can modify the prompt by adding specific requirements, constraints, or preferences. For Auth projects, consider mentioning your framework version, coding style, and any specific libraries you're using.

Related Prompts

💬 Comments

Loading comments...