ਛੇਤੀ ਸ਼ੁਰੂਆਤ: 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 ਅਤੇ ਕਲਾਇੰਟ ਸੀਕ੍ਰੇਟ ਕਾਪੀ ਕਰੋ। ਸੀਕ੍ਰੇਟ ਸਿਰਫ਼ ਇੱਕ ਵਾਰ ਦਿਖਾਇਆ ਜਾਂਦਾ ਹੈ।
ਆਪਣੇ ਐਨਵਾਇਰਨਮੈਂਟ ਵੇਰੀਏਬਲ ਜੋੜੋ
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ਆਪਣਾ ਇਸ਼ੂਅਰ ਖੋਜੋ
ਡਿਸਕਵਰੀ ਇਸ਼ੂਅਰ ਦੇ ਐਂਡਪੁਆਇੰਟ ਅਤੇ ਕੁੰਜੀਆਂ ਇੱਕ ਵਾਰ ਪੜ੍ਹ ਲੈਂਦੀ ਹੈ, ਇਸ ਲਈ ਕੁਝ ਵੀ ਹਾਰਡ-ਕੋਡ ਨਹੀਂ ਹੁੰਦਾ।
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`ਲੋਕਾਂ ਨੂੰ ਲਾਬੀ ’ਤੇ ਭੇਜੋ
ਇੱਕ ਰੂਟ ਹੈਂਡਲਰ ਇੱਕ PKCE ਵੈਰੀਫ਼ਾਇਰ ਅਤੇ ਇੱਕ state ਮੁੱਲ ਬਣਾਉਂਦਾ ਹੈ, ਉਹਨਾਂ ਨੂੰ ਥੋੜ੍ਹੇ ਸਮੇਂ ਦੀ ਕੁਕੀ ਵਿੱਚ ਰੱਖਦਾ ਹੈ, ਅਤੇ ਲਾਬੀ ’ਤੇ ਰੀਡਾਇਰੈਕਟ ਕਰਦਾ ਹੈ।
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 ਟੋਕਨ ਦਾ ਸਿਗਨੇਚਰ ਜਾਂਚਦੀ ਹੈ।
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 ਐਂਡਪੁਆਇੰਟ ’ਤੇ ਭੇਜੋ ਤਾਂ ਜੋ ਲਾਬੀ ਵੀ ਉਹਨਾਂ ਨੂੰ ਭੁੱਲ ਜਾਵੇ।
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
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 />
}