Next.js 的 AuthKit 函式庫為使用 WorkOS 和 AuthKit 與 Next.js 進行驗證和會話管理提供了方便的幫助程式。
注意:該程式庫旨在與 Next.js App Router 一起使用。
安裝軟體包:
npm i @workos-inc/authkit-nextjs
或者
yarn add @workos-inc/authkit-nextjs
確保.env.local
環境變數檔案中存在以下值。客戶端 ID 和 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
是用於加密會話 cookie 的私鑰。它的長度必須至少為 32 個字元。您可以使用 1Password 產生器或openssl
函式庫透過命令列產生強密碼:
openssl rand -base64 24
若要使用signOut
方法,您需要在 WorkOS 儀表板設定中的「重定向」下設定應用程式的主頁。
某些環境變數是可選的,可用於偵錯或配置 cookie 設定。
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
變數和 WorkOS 儀表板中設定的重定向 URI 相符。例如,如果您的重新導向 URI 是http://localhost:3000/auth/callback
那麼您可以將上述程式碼放入/app/auth/callback/route.ts
中。
您也可以透過將returnPathname
選項傳遞給handleAuth
來控制使用者登入後將發送到的路徑名,如下所示:
export const GET = handleAuth ( { returnPathname : '/dashboard' } ) ;
handleAuth
可以與多個選項一起使用。
選項 | 預設 | 描述 |
---|---|---|
returnPathname | / | 使用者登入後重定向到的路徑名 |
baseURL | undefined | 用於重定向 URI 的基本 URL,而不是請求中的 URL。如果應用程式在像 docker 這樣的容器中運行,其中主機名稱可能與請求中的主機名稱不同,則很有用 |
此函式庫依賴 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 預覽部署),請使用authkitMiddleware
中的redirectUri
選項:
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
包裝您的應用程式佈局,這為身份驗證邊緣情況添加了一些保護。
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
使用與 Next.js 匹配器相同的 glob 邏輯。
有時,如果您想編寫自訂中間件,檢查使用者會話會很有用。 getSession
幫助器方法將從 cookie 中檢索會話並驗證存取權杖。
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,並且必須在 try/catch 之外呼叫 Next 中的重定向。