원클릭으로
oidc-hosted-page-nextjs
Implement "Sign in with SSO" in Next.js applications using SSOJet OIDC Authorization Code flow with the App Router.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Implement "Sign in with SSO" in Next.js applications using SSOJet OIDC Authorization Code flow with the App Router.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Implement Machine-to-Machine (M2M) authentication using SSOJet OAuth2 Client Credentials flow for backend services and daemons.
Implement "Sign in with SSO" in native Android/Kotlin applications using SSOJet OIDC with AppAuth.
Implement "Sign in with SSO" in Angular SPA applications using SSOJet OIDC with PKCE.
Implement "Sign in with SSO" in ASP.NET Core applications using SSOJet OIDC middleware.
Implement "Sign in with SSO" in Go applications using SSOJet OIDC Authorization Code flow.
Implement "Sign in with SSO" in native iOS/Swift applications using SSOJet OIDC with AppAuth.
| 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. |
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).
openid-client (standard for Node.js OIDC integration).http://localhost:3000/api/auth/callback).
Run the following command to install the required OIDC library:
npm install openid-client
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).
// 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'],
});
}
Modify your existing login component (e.g., app/login/page.tsx) to include the "Sign in with SSO" toggle.
'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>
);
}
Create the necessary API routes to handle the OIDC flow.
1. Login Initiation Route (app/api/auth/login/route.ts):
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):
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));
}
}
npm run dev./login)./api/auth/callback and then to /dashboard.CLIENT_SECRET and ISSUER_URL in .env.local and access them via process.env.