कॉन्टेंट पर जाएँ
दस्तावेज़ · Next.js

क्विकस्टार्ट: Next.js

App Router वाले Next.js ऐप में साइन-इन जोड़ें। @usher/nextjs SDK जल्द आ रहा है; उसके आने तक यह गाइड स्टैंडर्ड OpenID Connect फ़्लो इस्तेमाल करती है, और SDK आपके लिए ठीक यही करेगा।

शुरू करने से पहले

  • App Router इस्तेमाल करने वाला Next.js 15 या 16 ऐप।
  • एक Usher एनवायरनमेंट। Usher Console में अपना प्रोजेक्ट खोलें, कोई एनवायरनमेंट चुनें, और उसका इश्यूअर नोट कर लें।

अपना ऐप रजिस्टर करें

Console में ऐप्लिकेशन पर जाएँ और एक वेब ऐप बनाएँ। यह रीडायरेक्ट URI बिल्कुल ऐसे ही जोड़ें:

http://localhost:3000/auth/callback

क्लाइंट ID और क्लाइंट सीक्रेट कॉपी करें। सीक्रेट सिर्फ़ एक बार दिखाया जाता है।

अपने एनवायरनमेंट वेरिएबल जोड़ें

.env.local
USHER_ISSUER=https://acme.usherid.com
USHER_CLIENT_ID=your_client_id
USHER_CLIENT_SECRET=your_client_secret
APP_URL=http://localhost:3000

OpenID Connect क्लाइंट इंस्टॉल करें

कोई भी सर्टिफ़ाइड क्लाइंट काम करता है। यह गाइड openid-client इस्तेमाल करती है, जो डिस्कवरी, PKCE और टोकन की जाँच सँभालता है।

टर्मिनल
pnpm add openid-client

अपना इश्यूअर खोजें

डिस्कवरी इश्यूअर के एंडपॉइंट और कुंजियाँ एक बार पढ़ लेती है, इसलिए कुछ भी हार्ड-कोड नहीं करना पड़ता।

lib/usher.ts
import * as client from 'openid-client'

let config: Promise<client.Configuration> | undefined

export function usher() {
  config ??= client.discovery(
    new URL(process.env.USHER_ISSUER!),
    process.env.USHER_CLIENT_ID!,
    process.env.USHER_CLIENT_SECRET!,
  )
  return config
}

export const redirectUri = `${process.env.APP_URL}/auth/callback`

लोगों को Lobby पर भेजें

एक रूट हैंडलर PKCE वेरिफ़ायर और state वैल्यू बनाता है, उन्हें कम समय तक चलने वाली कुकी में रखता है, और Lobby पर रीडायरेक्ट करता है।

app/auth/sign-in/route.ts
import * as client from 'openid-client'
import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'
import { redirectUri, usher } from '@/lib/usher'

export async function GET() {
  const config = await usher()
  const codeVerifier = client.randomPKCECodeVerifier()
  const state = client.randomState()

  const jar = await cookies()
  jar.set('usher_flow', JSON.stringify({ codeVerifier, state }), {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'lax',
    path: '/auth',
    maxAge: 600,
  })

  const url = client.buildAuthorizationUrl(config, {
    redirect_uri: redirectUri,
    scope: 'openid profile email offline_access',
    code_challenge: await client.calculatePKCECodeChallenge(codeVerifier),
    code_challenge_method: 'S256',
    state,
  })
  redirect(url.href)
}

कॉलबैक सँभालें

Usher व्यक्ति को एक कोड के साथ वापस भेजता है। उसके बदले टोकन लें; openid-client आपके लिए state, PKCE वेरिफ़ायर और ID टोकन का सिग्नेचर जाँच लेता है।

app/auth/callback/route.ts
import * as client from 'openid-client'
import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'
import { usher } from '@/lib/usher'

export async function GET(request: Request) {
  const config = await usher()
  const jar = await cookies()
  const flow = JSON.parse(jar.get('usher_flow')?.value ?? '{}')
  jar.delete('usher_flow')

  const tokens = await client.authorizationCodeGrant(config, new URL(request.url), {
    pkceCodeVerifier: flow.codeVerifier,
    expectedState: flow.state,
  })
  const claims = tokens.claims()! // sub, email, name, …

  // start your own session here: store claims.sub, and keep the refresh token server-side
  redirect('/')
}

साइन आउट

अपने ऐप में व्यक्ति का सेशन ख़त्म करें, फिर उन्हें Usher के end-session एंडपॉइंट पर भेजें, ताकि Lobby भी उन्हें भूल जाए।

app/auth/sign-out/route.ts
import * as client from 'openid-client'
import { redirect } from 'next/navigation'
import { usher } from '@/lib/usher'

export async function GET() {
  const config = await usher()
  // clear your own session first
  const url = client.buildEndSessionUrl(config, {
    post_logout_redirect_uri: process.env.APP_URL!,
  })
  redirect(url.href)
}

SDK के साथ

जब @usher/nextjs प्रकाशित होगा, तो यही ऐप कुछ ऐसा दिखेगा। नीचे दिया गया प्रीव्यू रिलीज़ से पहले बदल सकता है।

app/layout.tsx · app/page.tsx (प्रीव्यू)
// app/layout.tsx
import { UsherProvider } from '@usher/nextjs'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <UsherProvider>{children}</UsherProvider>
      </body>
    </html>
  )
}

// app/page.tsx
import { SignIn, UserButton, currentUser } from '@usher/nextjs'

export default async function Page() {
  const user = await currentUser()
  return user ? <UserButton /> : <SignIn />
}

आगे क्या करें