ไลบรารี AuthKit สำหรับ Next.js มอบตัวช่วยที่สะดวกสำหรับการตรวจสอบสิทธิ์และการจัดการเซสชันโดยใช้ WorkOS และ AuthKit กับ Next.js
หมายเหตุ: ไลบรารีนี้มีไว้สำหรับใช้กับเราเตอร์แอป Next.js
ติดตั้งแพ็คเกจด้วย:
npm i @workos-inc/authkit-nextjs
หรือ
yarn add @workos-inc/authkit-nextjs
ตรวจสอบให้แน่ใจว่าค่าต่อไปนี้แสดงอยู่ในไฟล์ตัวแปรสภาพแวดล้อม .env.local
ของคุณ รหัสไคลเอ็นต์และคีย์ API สามารถพบได้ในแดชบอร์ด WorkOS และสามารถกำหนดค่า URI การเปลี่ยนเส้นทางได้จากที่นั่น
WORKOS_CLIENT_ID= " client_... " # retrieved from the WorkOS dashboard
WORKOS_API_KEY= " sk_test_... " # retrieved from the WorkOS dashboard
WORKOS_COOKIE_PASSWORD= " <your password> " # generate a secure password here
NEXT_PUBLIC_WORKOS_REDIRECT_URI= " http://localhost:3000/callback " # configured in the WorkOS dashboard
WORKOS_COOKIE_PASSWORD
คือคีย์ส่วนตัวที่ใช้ในการเข้ารหัสคุกกี้เซสชัน ต้องมีความยาวอย่างน้อย 32 ตัวอักษร คุณสามารถใช้ตัวสร้าง 1Password หรือไลบรารี openssl
เพื่อสร้างรหัสผ่านที่รัดกุมผ่านทางบรรทัดคำสั่ง:
openssl rand -base64 24
หากต้องการใช้วิธี signOut
คุณจะต้องตั้งค่าหน้าแรกของแอปในการตั้งค่าแดชบอร์ด WorkOS ใต้ "การเปลี่ยนเส้นทาง"
ตัวแปรสภาพแวดล้อมบางอย่างเป็นทางเลือกและสามารถใช้เพื่อแก้ไขข้อบกพร่องหรือกำหนดการตั้งค่าคุกกี้ได้
WORKOS_COOKIE_MAX_AGE= ' 600 ' # maximum age of the cookie in seconds. Defaults to 400 days, the maximum allowed in Chrome
WORKOS_COOKIE_DOMAIN= ' example.com '
WORKOS_COOKIE_NAME= ' authkit-cookie '
WORKOS_API_HOSTNAME= ' api.workos.com ' # base WorkOS API URL
WORKOS_API_HTTPS=true # whether to use HTTPS in API calls
WORKOS_API_PORT=3000 # port to use for API calls
WORKOS_COOKIE_DOMAIN
สามารถใช้เพื่อแชร์เซสชัน WorkOS ระหว่างแอป/โดเมน หมายเหตุ: WORKOS_COOKIE_PASSWORD
จะต้องเหมือนกันในทุกแอป/โดเมน ไม่จำเป็นสำหรับกรณีการใช้งานส่วนใหญ่
WorkOS กำหนดให้คุณต้องมี URL เรียกกลับเพื่อเปลี่ยนเส้นทางผู้ใช้กลับไปหลังจากที่พวกเขาตรวจสอบสิทธิ์แล้ว ในแอป Next.js ให้เปิดเผยเส้นทาง API และเพิ่มรายการต่อไปนี้
import { handleAuth } from '@workos-inc/authkit-nextjs' ;
export const GET = handleAuth ( ) ;
ตรวจสอบให้แน่ใจว่าเส้นทางนี้ตรงกับตัวแปร WORKOS_REDIRECT_URI
และ URI การเปลี่ยนเส้นทางที่กำหนดค่าไว้ในแดชบอร์ด WorkOS ของคุณ ตัวอย่างเช่น หาก URI การเปลี่ยนเส้นทางของคุณคือ http://localhost:3000/auth/callback
คุณจะต้องใส่โค้ดด้านบนใน /app/auth/callback/route.ts
คุณยังสามารถควบคุมชื่อพาธที่ผู้ใช้จะถูกส่งไปหลังจากลงชื่อเข้าใช้โดยส่งตัวเลือก returnPathname
เพื่อ handleAuth
ดังนี้:
export const GET = handleAuth ( { returnPathname : '/dashboard' } ) ;
handleAuth
สามารถใช้ได้หลายตัวเลือก
ตัวเลือก | ค่าเริ่มต้น | คำอธิบาย |
---|---|---|
returnPathname | / | ชื่อพาธที่จะเปลี่ยนเส้นทางผู้ใช้ไปหลังจากลงชื่อเข้าใช้ |
baseURL | undefined | URL พื้นฐานที่จะใช้สำหรับ URI การเปลี่ยนเส้นทางแทนที่จะเป็น URL ในคำขอ มีประโยชน์หากแอปทำงานในคอนเทนเนอร์ เช่น นักเทียบท่า ซึ่งชื่อโฮสต์อาจแตกต่างจากชื่อในคำขอ |
ไลบรารีนี้อาศัยมิดเดิลแวร์ Next.js เพื่อจัดเตรียมการจัดการเซสชันสำหรับเส้นทาง วางสิ่งต่อไปนี้ในไฟล์ middleware.ts
ของคุณในรูทของโปรเจ็กต์ของคุณ:
import { authkitMiddleware } from '@workos-inc/authkit-nextjs' ;
export default authkitMiddleware ( ) ;
// Match against pages that require auth
// Leave this out if you want auth on every resource (including images, css etc.)
export const config = { matcher : [ '/' , '/admin' ] } ;
มิดเดิลแวร์สามารถกำหนดค่าได้หลายตัวเลือก
ตัวเลือก | ค่าเริ่มต้น | คำอธิบาย |
---|---|---|
redirectUri | undefined | ใช้ในกรณีที่คุณต้องการตั้งค่า URI การเปลี่ยนเส้นทางแบบไดนามิก (เช่น การใช้งานการแสดงตัวอย่าง Vercel) |
middlewareAuth | undefined | ใช้เพื่อกำหนดค่าตัวเลือกการตรวจสอบสิทธิ์มิดเดิลแวร์ ดูการตรวจสอบมิดเดิลแวร์สำหรับรายละเอียดเพิ่มเติม |
debug | false | เปิดใช้งานบันทึกการแก้ไขข้อบกพร่อง |
signUpPaths | [] | ใช้เพื่อระบุเส้นทางที่ควรใช้คำแนะนำบนหน้าจอ 'สมัคร' เมื่อเปลี่ยนเส้นทางไปยัง AuthKit |
ในกรณีที่คุณต้องการตั้งค่า URI การเปลี่ยนเส้นทางแบบไดนามิก (เช่น การปรับใช้การแสดงตัวอย่าง Vercel) ให้ใช้ตัวเลือก redirectUri
ใน authkitMiddleware
:
import { authkitMiddleware } from '@workos-inc/authkit-nextjs' ;
export default authkitMiddleware ( {
redirectUri : 'https://foo.example.com/callback' ,
} ) ;
// Match against pages that require auth
// Leave this out if you want auth on every resource (including images, css etc.)
export const config = { matcher : [ '/' , '/admin' ] } ;
URI การเปลี่ยนเส้นทางแบบกำหนดเองจะถูกใช้บน URI การเปลี่ยนเส้นทางที่กำหนดค่าในตัวแปรสภาพแวดล้อม
AuthKitProvider
ใช้ AuthKitProvider
เพื่อรวมเค้าโครงแอปของคุณ ซึ่งเพิ่มการป้องกันบางอย่างสำหรับกรณี auth edge
import { AuthKitProvider } from '@workos-inc/authkit-nextjs' ;
export default function RootLayout ( { children } : { children : React . ReactNode } ) {
return (
< html lang = "en" >
< body >
< AuthKitProvider > { children } < / AuthKitProvider >
< / body >
< / html >
) ;
}
สำหรับเพจที่คุณต้องการแสดงมุมมองที่ลงชื่อเข้าใช้และออกจากระบบ ให้ใช้ withAuth
เพื่อดึงโปรไฟล์ผู้ใช้จาก WorkOS
import Link from 'next/link' ;
import { getSignInUrl , getSignUpUrl , withAuth , signOut } from '@workos-inc/authkit-nextjs' ;
export default async function HomePage ( ) {
// Retrieves the user from the session or returns `null` if no user is signed in
const { user } = await withAuth ( ) ;
if ( ! user ) {
// Get the URL to redirect the user to AuthKit to sign in
const signInUrl = await getSignInUrl ( ) ;
// Get the URL to redirect the user to AuthKit to sign up
const signUpUrl = await getSignUpUrl ( ) ;
return (
< >
< Link href = { signInUrl } > Log in < / Link >
< Link href = { signUpUrl } > Sign Up < / Link >
< / >
) ;
}
return (
< form
action = { async ( ) => {
'use server' ;
await signOut ( ) ;
} }
>
< p > Welcome back { user ?. firstName && `, ${ user ?. firstName } ` } < / p >
< button type = "submit" > Sign out < / button >
< / form >
) ;
}
สำหรับเพจที่จำเป็นต้องมีผู้ใช้ที่ลงชื่อเข้าใช้ คุณสามารถใช้ตัวเลือก ensureSignedIn
:
const { user } = await withAuth ( { ensureSignedIn : true } ) ;
การเปิดใช้ ensureSignedIn
จะเปลี่ยนเส้นทางผู้ใช้ไปยัง AuthKit หากพวกเขาพยายามเข้าถึงเพจโดยไม่ได้รับการตรวจสอบสิทธิ์
ลักษณะการทำงานเริ่มต้นของไลบรารีนี้คือการขอการรับรองความถูกต้องผ่านวิธี withAuth
ต่อหน้า มีกรณีการใช้งานบางกรณีที่คุณไม่ต้องการโทร withAuth
(เช่น คุณไม่ต้องการข้อมูลผู้ใช้สำหรับเพจของคุณ) หรือหากคุณต้องการวิธีการ "ปลอดภัยตามค่าเริ่มต้น" โดยที่ทุกเส้นทางที่กำหนดไว้ในตัวจับคู่มิดเดิลแวร์ของคุณได้รับการปกป้อง เว้นแต่จะระบุไว้เป็นอย่างอื่น ในกรณีดังกล่าว คุณสามารถเลือกใช้การรับรองความถูกต้องมิดเดิลแวร์แทนได้:
import { authkitMiddleware } from '@workos-inc/authkit-nextjs' ;
export default authkitMiddleware ( {
middlewareAuth : {
enabled : true ,
unauthenticatedPaths : [ '/' , '/about' ] ,
} ,
} ) ;
// Match against pages that require auth
// Leave this out if you want auth on every resource (including images, css etc.)
export const config = { matcher : [ '/' , '/admin/:path*' , '/about' ] } ;
ในตัวอย่างข้างต้น หน้า /admin
กำหนดให้ผู้ใช้ต้องลงชื่อเข้าใช้ ในขณะที่ /
และ /about
สามารถเข้าถึงได้โดยไม่ต้องลงชื่อเข้าใช้
unauthenticatedPaths
ใช้ตรรกะ glob เดียวกันกับตัวจับคู่ Next.js
บางครั้งการตรวจสอบเซสชันผู้ใช้ก็มีประโยชน์หากคุณต้องการเขียนมิดเดิลแวร์ที่กำหนดเอง เมธอดตัวช่วย getSession
จะดึงเซสชันจากคุกกี้และตรวจสอบโทเค็นการเข้าถึง
import { authkitMiddleware , getSession } from '@workos-inc/authkit-nextjs' ;
import { NextRequest , NextFetchEvent } from 'next/server' ;
export default async function middleware ( request : NextRequest , event : NextFetchEvent ) {
// authkitMiddleware will handle refreshing the session if the access token has expired
const response = await authkitMiddleware ( ) ( request , event ) ;
// If session is undefined, the user is not authenticated
const session = await getSession ( response ) ;
// ...add additional middleware logic here
return response ;
}
// Match against pages that require auth
export const config = { matcher : [ '/' , '/account/:path*' ] } ;
ใช้วิธี signOut
เพื่อออกจากระบบของผู้ใช้ที่เข้าสู่ระบบในปัจจุบัน และเปลี่ยนเส้นทางไปยังหน้าแรกของแอปของคุณ การเปลี่ยนเส้นทางหน้าแรกได้รับการตั้งค่าไว้ในการตั้งค่าแดชบอร์ด WorkOS ของคุณภายใต้ "การเปลี่ยนเส้นทาง"
แสดงผลองค์ประกอบ Impersonation
ในแอปของคุณเพื่อให้ชัดเจนเมื่อมีคนแอบอ้างเป็นผู้ใช้ ส่วนประกอบจะแสดงเฟรมพร้อมข้อมูลบางอย่างเกี่ยวกับผู้ใช้ที่ถูกแอบอ้าง ตลอดจนปุ่มสำหรับหยุดการแอบอ้างบุคคลอื่น
import { Impersonation } from '@workos-inc/authkit-nextjs' ;
export default function App ( ) {
return (
< div >
< Impersonation / >
{ /* Your app content */ }
< / div >
) ;
}
บางครั้งการรับโทเค็นการเข้าถึงโดยตรงก็มีประโยชน์ เช่น การร้องขอ API ไปยังบริการอื่น
import { withAuth } from '@workos-inc/authkit-nextjs' ;
export default async function HomePage ( ) {
const { accessToken } = await withAuth ( ) ;
if ( ! accessToken ) {
return < div > Not signed in < / div > ;
}
const serviceData = await fetch ( '/api/path' , {
headers : {
Authorization : `Bearer ${ accessToken } ` ,
} ,
} ) ;
return < div > { serviceData } < / div > ;
}
ใช้เมธอด refreshSession
ในการดำเนินการของเซิร์ฟเวอร์หรือตัวจัดการเส้นทางเพื่อดึงรายละเอียดเซสชันล่าสุด รวมถึงการเปลี่ยนแปลงในบทบาทหรือสิทธิ์ของผู้ใช้
สามารถส่งพารามิเตอร์ organizationId
ไปยัง refreshSession
เพื่อสลับเซสชันไปยังองค์กรอื่นได้ หากเซสชันปัจจุบันไม่ได้รับอนุญาตสำหรับองค์กรถัดไป ข้อผิดพลาดในการรับรองความถูกต้องที่เหมาะสมจะถูกส่งกลับ
ตัวเลือก signUpPaths
สามารถส่งผ่านไปยัง authkitMiddleware
เพื่อระบุเส้นทางที่ควรใช้คำแนะนำบนหน้าจอ 'ลงทะเบียน' เมื่อเปลี่ยนเส้นทางไปยัง AuthKit สิ่งนี้มีประโยชน์สำหรับกรณีที่คุณต้องการให้เส้นทางที่กำหนดให้การรับรองความถูกต้องถือเป็นหน้าลงทะเบียน
import { authkitMiddleware } from '@workos-inc/authkit-nextjs' ;
export default authkitMiddleware ( {
signUpPaths : [ '/account/sign-up' , '/dashboard/:path*' ] ,
} ) ;
หากต้องการเปิดใช้งานบันทึกการแก้ไขข้อบกพร่อง ให้เริ่มต้นมิดเดิลแวร์โดยเปิดใช้งานการตั้งค่าสถานะการแก้ไขข้อบกพร่อง
import { authkitMiddleware } from '@workos-inc/authkit-nextjs' ;
export default authkitMiddleware ( { debug : true } ) ;
การล้อมการเรียก withAuth({ ensureSignedIn: true })
ในบล็อก try/catch จะทำให้เกิดข้อผิดพลาด NEXT_REDIRECT
เนื่องจาก withAuth
จะพยายามเปลี่ยนเส้นทางผู้ใช้ไปยัง AuthKit หากตรวจไม่พบเซสชัน และการเปลี่ยนเส้นทางใน Next จะต้องถูกเรียกนอก try/catch