Skip to main content
SlugShare uses NextAuth.js v5 to handle user authentication. Students can sign in using their Google account (via OAuth) or with email and password credentials.

Authentication Methods

The recommended sign-in method for UCSC students. Google OAuth provides a secure, passwordless authentication experience.
app/auth.config.ts
import Google from "next-auth/providers/google";

providers: [
  Google({
    clientId: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
  })
]
Benefits:
  • No password to remember
  • Automatic account creation on first sign-in
  • Uses UCSC Google Workspace credentials

Sign In Flow

1

Navigate to login page

Users visit /auth/login to access the sign-in form.The auth configuration automatically redirects authenticated users:
auth.config.ts
pages: {
  signIn: "/auth/login",
  signOut: "/auth/login",
}
2

Choose authentication method

Users can either:
  • Click “Sign in with Google” for OAuth authentication
  • Enter email and password for credentials-based login
3

Authentication verification

NextAuth.js validates the credentials or OAuth token and creates a session.
auth.config.ts
callbacks: {
  async jwt({ token, user }) {
    if (user) {
      token.id = user.id;
    }
    return token;
  },
  async session({ session, token }) {
    if (session.user) {
      session.user.id = token.id as string;
    }
    return session;
  },
}
4

Redirect to dashboard

After successful authentication, users are redirected to /dashboard where they can view their points balance and create requests.

Protected Routes

SlugShare uses NextAuth.js middleware to protect authenticated routes. The dashboard and all request-related pages require authentication.
auth.config.ts
callbacks: {
  authorized({ auth, request: { nextUrl } }) {
    const isLoggedIn = !!auth?.user;
    const isOnDashboard = nextUrl.pathname.startsWith("/dashboard");
    
    if (isOnDashboard) {
      if (isLoggedIn) return true;
      return false; // Redirect unauthenticated users to login page
    } else if (isLoggedIn && nextUrl.pathname === "/auth/login") {
      return Response.redirect(new URL("/dashboard", nextUrl));
    }
    return true;
  },
}

Server-Side Authentication Check

API routes verify authentication using the getCurrentUser() helper:
app/api/requests/route.ts
import { getCurrentUser } from "@/lib/auth";

export async function GET() {
  const user = await getCurrentUser();

  if (!user || !user.id) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  // Fetch requests for authenticated user
}

Session Management

SlugShare uses JWT-based sessions for fast, stateless authentication:
auth.ts
export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: PrismaAdapter(prisma),
  session: { strategy: "jwt" },
  secret: process.env.AUTH_SECRET,
  ...authConfig,
});
JWT sessions are cached in the token. User information does not automatically update until the next sign-in.

Sign Out

Users can sign out from any page. The sign-out action clears the session and redirects to the login page:
import { signOut } from "@/auth";

await signOut({ redirectTo: "/auth/login" });

Environment Variables

Required environment variables for authentication:
.env
AUTH_SECRET="your-secret-key"  # Generate with: openssl rand -base64 32
GOOGLE_CLIENT_ID="your-google-client-id"
GOOGLE_CLIENT_SECRET="your-google-client-secret"

Build docs developers (and LLMs) love