Back to skills
SkillHub ClubShip Full StackFull StackFrontend

oidc-hosted-page-nextjs

Implement "Sign in with SSO" in Next.js applications using SSOJet OIDC Authorization Code flow with the App Router.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3
Hot score
80
Updated
March 20, 2026
Overall rating
C0.8
Composite score
0.8
Best-practice grade
B81.2

Install command

npx @skill-hub/cli install ssojet-skills-oidc-hosted-page-nextjs

Repository

ssojet/skills

Skill path: skills/authentication/oidc-hosted-page-nextjs

Implement "Sign in with SSO" in Next.js applications using SSOJet OIDC Authorization Code flow with the App Router.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack, Frontend.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: ssojet.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install oidc-hosted-page-nextjs into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/ssojet/skills before adding oidc-hosted-page-nextjs to shared team environments
  • Use oidc-hosted-page-nextjs for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: oidc-hosted-page-nextjs
description: Implement "Sign in with SSO" in Next.js applications using SSOJet OIDC Authorization Code flow with the App Router.
---

# Implement SSOJet OIDC (Next.js)

This expert AI assistant guide walks you through integrating "Sign in with SSO" functionality into an existing login page in a Next.js application using SSOJet as an OIDC identity provider. The goal is to modify the existing login flow to add SSO support without disrupting the current traditional login functionality (e.g., email/password).

## 1. Prerequisites

- An existing Next.js application with a login page.
- Basic knowledge of Next.js and its common tools (e.g., App Router).
- An active SSOJet account.
- [SSO Connection Setup Guide](https://docs.ssojet.com/en/how-to-guides/integrations//)
- Required libraries: `openid-client` (standard for Node.js OIDC integration).

## 2. Implementation Steps

### Step 1: Create Application in SSOJet

1. Log in to the SSOJet Dashboard.
2. Navigate to **Applications**.
3. Create a new application (e.g., "MyNextjsApp", type **Regular Web App**).
4. Configure the callback URI (e.g., `http://localhost:3000/api/auth/callback`).
5. Retrieve **Client ID** and **Client Secret**.
6. Copy the **Issuer URL** from the **Advanced > Endpoints** section.
7. ![Create Application in SSOJet](/img/ssojet-applications-stepX.png)

### Step 2: Modify the Existing Next.js Project

#### Substep 2.1: Install Dependencies

Run the following command to install the required OIDC library:

```bash
npm install openid-client
```

#### Substep 2.2: Configure OIDC

Configure the OIDC provider with your SSOJet credentials. It is recommended to create a dedicated utility file for this configuration (e.g., `lib/oidc.ts`).

```typescript
// lib/oidc.ts
import { Issuer } from 'openid-client';

export async function getClient() {
  const ssojetIssuer = await Issuer.discover('${ISSUER_URL}'); // e.g. https://auth.ssojet.com
  return new ssojetIssuer.Client({
    client_id: '${cli_curf51oulvtc716e50eg.ad4a67ec19ac4507b744a1686ec9bff8.MGMpt3uV99Lftv5KkHF7pk}',
    client_secret: '${CLIENT_SECRET}',
    redirect_uris: ['http://localhost:3000/api/auth/callback'],
    response_types: ['code'],
  });
}
```

#### Substep 2.3: Update Login Page/UI

Modify your existing login component (e.g., `app/login/page.tsx`) to include the "Sign in with SSO" toggle.

```tsx
'use client';

import { useState } from 'react';
import { useRouter } from 'next/navigation';

export default function LoginPage() {
  const [isSSO, setIsSSO] = useState(false);
  const [email, setEmail] = useState('');
  const router = useRouter();

  const handleLogin = async (e: React.FormEvent) => {
    e.preventDefault();
    if (isSSO) {
      // Trigger SSO login by redirecting to our API route
      window.location.href = `/api/auth/login?login_hint=${encodeURIComponent(email)}`;
    } else {
      // Existing password login logic here
      console.log('Processing traditional login...');
    }
  };

  return (
    <div className="login-container">
      <h1>Sign In</h1>
      <form onSubmit={handleLogin} className="flex flex-col gap-4">
        <div>
          <label>Email</label>
          <input
            type="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            required
            className="border p-2 rounded"
          />
        </div>

        {!isSSO && (
          <div>
            <label>Password</label>
            <input type="password" required className="border p-2 rounded" />
          </div>
        )}

        <button type="submit" className="bg-blue-600 text-white p-2 rounded">
          {isSSO ? 'Continue with SSO' : 'Sign In'}
        </button>

        <button
          type="button"
          onClick={() => setIsSSO(!isSSO)}
          className="text-sm text-blue-500 underline"
        >
          {isSSO ? 'Back to Password Login' : 'Sign in with SSO'}
        </button>
      </form>
    </div>
  );
}
```

#### Substep 2.4: Update Backend Logic

Create the necessary API routes to handle the OIDC flow.

**1. Login Initiation Route** (`app/api/auth/login/route.ts`):

```typescript
import { NextResponse } from 'next/server';
import { getClient } from '@/lib/oidc';

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const login_hint = searchParams.get('login_hint');
  const client = await getClient();

  // Generate a random state for CSRF protection
  const state = Math.random().toString(36).substring(2, 15);

  const authorizationUrl = client.authorizationUrl({
    scope: 'openid profile email',
    login_hint: login_hint || undefined,
    state,
  });

  const response = NextResponse.redirect(authorizationUrl);
  // Store state in a cookie to verify in the callback
  response.cookies.set('oidc_state', state, { 
    httpOnly: true, 
    secure: true, 
    sameSite: 'lax',
    maxAge: 3600 
  });

  return response;
}
```

**2. Callback Handler Route** (`app/api/auth/callback/route.ts`):

```typescript
import { NextRequest, NextResponse } from 'next/server';
import { getClient } from '@/lib/oidc';

export async function GET(request: NextRequest) {
  const client = await getClient();
  const params = client.callbackParams(request.url);
  
  try {
    const storedState = request.cookies.get('oidc_state')?.value;
    const tokenSet = await client.callback('http://localhost:3000/api/auth/callback', params, { state: storedState });
    const userinfo = await client.userinfo(tokenSet.access_token!);
    
    // TODO: Create a session for the user based on `userinfo`
    console.log('Authenticated User:', userinfo);

    // Redirect to the dashboard or intended page
    return NextResponse.redirect(new URL('/dashboard', request.url));
  } catch (error) {
    console.error('OIDC Callback Error:', error);
    return NextResponse.redirect(new URL('/login?error=oidc_failed', request.url));
  }
}
```

### Step 3: Test the Modified Connection

1. Start your application: `npm run dev`.
2. Navigate to your login page (e.g., `/login`).
3. Verify that the traditional login form (Email + Password) is visible by default.
4. Click **"Sign in with SSO"** and ensure:
   - The password field disappears.
   - The submit button changes to "Continue with SSO".
5. Enter a test email and submit.
   - You should be redirected to the SSOJet login page.
6. Authenticate with SSOJet.
   - You should be redirected back to `/api/auth/callback` and then to `/dashboard`.

## 3. Additional Considerations

- **Error Handling**: Enhance the callback route to handle specific OIDC errors gracefully.
- **Styling**: Adapt the example CSS classes to match your application's design system.
- **Security**: Integrate the user information returned in the callback with your existing session management system (e.g., setting cookies or JWTs).
- **Environment Variables**: Store sensitive values like `CLIENT_SECRET` and `ISSUER_URL` in `.env.local` and access them via `process.env`.

## 4. Support

- **Contact SSOJet support**: Reach out if you have integration questions.
- **Check application logs**: Use server-side logging to debug OIDC flow issues.
- **Library Documentation**: Refer to the [openid-client documentation](https://github.com/panva/node-openid-client) for advanced configuration.
oidc-hosted-page-nextjs | SkillHub