સામગ્રી પર જાઓ
ડૉક્સ · 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`

લોકોને લૉબી પર મોકલો

એક route handler PKCE વેરિફાયર અને state વૅલ્યૂ બનાવે છે, તેમને ટૂંકા સમયની કૂકીમાં રાખે છે, અને લૉબી પર રીડાયરેક્ટ કરે છે.

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 એન્ડપૉઇન્ટ પર મોકલો, જેથી લૉબી પણ તેમને ભૂલી જાય.

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 />
}

આગળનાં પગલાં