Auth0 Next.js SDK 是一個用於在 Next.js 應用程式中實現使用者身份驗證的程式庫。
文件 - 入門 - API 參考 - 回饋
快速入門 - 我們將 Auth0 新增到 Next.js 應用程式的指南。
常見問題 - 有關 nextjs-auth0 的常見問題。
範例 - 針對不同用例的大量範例。
安全 - 您應該檢查的一些重要安全聲明。
架構 - SDK 的架構概述。
測試 - 一些幫助測試您的 nextjs-auth0 應用程式。
部署 - 我們如何將範例應用程式部署到 Vercel。
文件網站 - 瀏覽我們的文件網站並了解有關 Auth0 的更多資訊。
使用 npm:
npm install @auth0/nextjs-auth0
該函式庫需要 Node.js 16 LTS 和更新的 LTS 版本。
在 Auth0 儀表板中建立常規 Web 應用程式。
如果您使用的是現有應用程序,請驗證您是否已在常規 Web 應用程式中配置以下設定:
按一下應用程式頁面的「設定」標籤。
向下捲動並點擊“顯示進階設定”連結。
在“進階設定”下,按一下“OAuth”標籤。
確保“JsonWebToken 簽章演算法”設定為
RS256
並啟用“OIDC Conformant”。
接下來,在「設定」頁面的「應用程式 URI」部分下為您的應用程式配置以下 URL:
允許的回呼 URL : http://localhost:3000/api/auth/callback
允許的登出 URL : http://localhost:3000/
記下「基本資訊」部分下的Client ID 、 Client Secret和Domain值。您在下一步中將需要這些值。
您需要允許 Next.js 應用程式與 Auth0 正確通訊。您可以透過在根專案目錄下建立一個.env.local
檔案來定義必要的 Auth0 配置值,如下所示:
# 用於加密會話 cookie 的長秘密值AUTH0_SECRET='LONG_RANDOM_VALUE'# 應用程式的基本 urlAUTH0_BASE_URL='http://localhost:3000'# Auth0 租用戶網域的 urlAUTH0_ISSUER_BASE_URLAU'https://YOUR_URLAUc.您的Auth0 應用程式的客戶端IDAUTH0_CLIENT_ID='YOUR_AUTH0_CLIENT_ID'# 您的Auth0 應用程式的客戶端金鑰AUTH0_CLIENT_SECRET='YOUR_AUTH0_CLIENT_SECRET'
您可以執行以下命令來為AUTH0_SECRET
值產生適當的字串:
節點-e“console.log(crypto.randomBytes(32).toString('hex'))”
您可以在「模組配置」文件的「配置屬性」部分中查看 Auth0 配置選項的完整清單。
有關在 Next.js 中載入環境變數的更多詳細信息,請訪問「環境變數」文件。
將handleAuth()
新增至您的應用程式中,這會在背景建立以下路由處理程序,執行身分驗證流程的不同部分:
/api/auth/login
:您的 Next.js 應用程式將使用者重新導向到您的身分提供者以便他們登入(您可以選擇傳遞returnTo
參數以在登入後返回自訂相對 URL,例如/api/auth/login?returnTo=/profile
)。
/api/auth/callback
:您的身分提供者在使用者成功登入後將使用者重新導向至此路由。
/api/auth/logout
:您的 Next.js 應用程式登出使用者。
/api/auth/me
:您可以取得 JSON 格式的使用者個人資料資訊。
根據您的路由器繼續設定:
頁面路由器
應用程式路由器
在/pages/api
目錄下建立動態 API 路由處理程序:
在/pages/api/
目錄下建立auth
目錄。
在新建立的auth
目錄下建立[auth0].js
檔案。
動態 API 路由檔案的路徑為/pages/api/auth/[auth0].js
。如下填入該文件:
從'@auth0/nextjs-auth0'導入{handleAuth};導出預設handleAuth();
使用UserProvider
元件包裝pages/_app.js
元件:
//pages/_app.jsimport React from 'react';import { UserProvider } from '@auth0/nextjs-auth0/client';匯出預設函數 App({ Component, pageProps }) { return (<UserProvider> <Component {...pageProps} /></UserProvider> );}
現在,您可以透過檢查useUser()
掛鉤傳回的user
物件是否已定義來確定使用者是否已通過身份驗證。您也可以透過將使用者重新導向到適當的自動產生的路由,從 Next.js 應用程式的前端層登入或登出使用者:
// pages/index.jsimport { useUser } from '@auth0/nextjs-auth0/client';匯出預設函數 Index() { const { 用戶,錯誤,正在載入 } = useUser(); if (isLoading) return <div>正在載入...</div>; 如果(錯誤)返回<div>{error.message}</div>; if (user) {return ( <div>歡迎{user.name}!<a href="/api/auth/logout">註銷</a> </div>); } 返回<a href="/api/auth/login">登入</a>;}
接下來的 linting 規則可能建議使用
Link
元件而不是錨標記。Link
元件旨在執行頁面之間的客戶端轉換。由於連結指向 API 路由而不是頁面,因此您應該將它們保留為錨標記。
在繼續之前,請先查看將此 SDK 與 React Server 元件一起使用。
在/app/api
目錄下建立一個包羅萬象的動態 API 路由處理程序(嚴格來說,您不需要將 API 路由放在/api
下,但為了簡單起見,我們保留了約定):
在/app/
目錄下建立一個api
目錄。
在新建立的/app/api/
目錄下建立auth
目錄。
在新建立的auth
目錄下建立[auth0]
目錄。
在新建立的[auth0]
目錄下建立route.js
檔案。
動態 API 路由檔案的路徑為/app/api/auth/[auth0]/route.js
。如下填入該文件:
從'@auth0/nextjs-auth0'導入{handleAuth};導出const GET =handleAuth();
UserProvider
新增至您的佈局中使用UserProvider
組件包裝您的app/layout.js
組件:
// app/layout.jsimport React from 'react';import { UserProvider } from '@auth0/nextjs-auth0/client';匯出預設函數 App({children }) { 返回(<UserProvider> <body>{children}</body></UserProvider> );}
現在,您可以透過檢查useUser()
掛鉤傳回的user
物件是否已定義來確定使用者是否已通過身份驗證。您也可以透過將使用者重新導向到適當的自動產生的路由,從 Next.js 應用程式的前端層登入或登出使用者:
// pages/index.js'use client';import { useUser } from '@auth0/nextjs-auth0/client';匯出預設函數 Index() { const { 用戶,錯誤,正在載入 } = useUser(); if (isLoading) return <div>正在載入...</div>; 如果(錯誤)返回<div>{error.message}</div>; if (user) {return ( <div>歡迎{user.name}!<a href="/api/auth/logout">註銷</a> </div>); } 返回<a href="/api/auth/login">登入</a>;}
接下來的 linting 規則可能建議使用
Link
元件而不是錨標記。Link
元件旨在執行頁面之間的客戶端轉換。由於連結指向 API 路由而不是頁面,因此您應該將它們保留為錨標記。
應用程式目錄中的伺服器元件(包括頁面和佈局)無法寫入 cookie。
如果您僅依賴伺服器元件來讀取和更新會話,您應該注意以下事項:
如果您有滾動會話(此 SDK 的預設設定),則當使用者造訪您的網站時,到期日期不會更新。因此會話可能會比您預期的更早過期(您可以使用withMiddlewareAuthRequired
來緩解這種情況)。
如果刷新存取令牌,新的存取令牌將不會保留在會話中。因此,後續嘗試取得存取權杖將始終導致刷新會話中過期的存取權杖。
如果您對會話進行任何其他更新,它們將不會在請求之間保留。
Cookie可以從中介軟體、路由處理程序和伺服器操作寫入。
有關其他綜合範例,請參閱 Examples.md 文件。
import * from @auth0/nextjs-auth0
import * from @auth0/nextjs-auth0/edge
配置選項和環境變數
初始化Auth0
處理授權
處理登入
處理回調
處理註銷
句柄設定檔
withApiAuthRequired
需要頁面驗證
取得會話
更新會話
獲取訪問令牌
withMiddlewareAuthRequired(僅限 Edge)
import * from @auth0/nextjs-auth0/client
使用者提供者
使用用戶
需要頁面驗證
import * from @auth0/nextjs-auth0/testing
產生會話Cookie
訪問自動生成的 API 文件以了解更多詳細信息
所有 cookie 將設定為HttpOnly, SameSite=Lax
,如果應用程式的AUTH0_BASE_URL
為https
,則所有 cookie 將設定為Secure
。
HttpOnly
設定將確保客戶端 JavaScript 無法存取 cookie,以減少 XSS 攻擊的攻擊面。
SameSite=Lax
設定將有助於減輕 CSRF 攻擊。透過閱讀「即將發生的瀏覽器行為變化:開發人員需要了解的內容」部落格文章,了解更多關於 SameSite 的資訊。
許多託管提供者將提供在邊緣快取您的內容的服務,以便盡快向您的用戶提供資料。例如,如果您在回應中提供必要的快取標頭,Vercel 將在 Vercel Edge Network 上快取所有靜態內容和無伺服器功能的內容。
快取任何需要身份驗證的回應通常是一個壞主意,即使回應的內容看起來可以安全地緩存,但回應中可能還有其他不安全的資料。
預設情況下,此 SDK 提供滾動會話,這表示讀取會話的任何回應都將具有Set-Cookie
標頭來更新 cookie 的過期時間。 Vercel 和潛在的其他託管提供者在快取的回應中包含Set-Cookie
標頭,因此即使您認為可以公開快取回應的內容,回應的Set-Cookie
標頭也不能。
檢查您的託管提供者的快取規則,但一般來說,您不應該快取需要身份驗證或甚至觸摸會話來檢查身份驗證的回應(例如,當使用withApiAuthRequired
、 withPageAuthRequired
甚至只是getSession
或getAccessToken
時)。
來自redirect_uri
回呼中的Auth0 的錯誤可能包含透過OpenID Connect error
和error_description
查詢參數反映的使用者輸入。因此,我們對IdentityProviderError
的message
、 error
和error_description
屬性進行一些基本的轉義。
但是,如果您編寫自己的錯誤處理程序,則不應在不使用模板引擎的情況下呈現錯誤message
或error
和error_description
屬性,該模板引擎首先會正確地將它們轉義為其他 HTML 上下文。
借助 Next.js,您可以使用基本路徑在域的子路徑下部署 Next.js 應用程序,並使用國際化路由提供國際化 (i18n) 路由。
如果您使用這些功能,您的應用程式的 url 將會發生變化,因此 nextjs-auth0 路由的 url 將會發生變化。為了適應這種情況,您可以在 SDK 中的多個位置自訂 url。
例如,如果basePath: '/foo'
您應該將其新增至Auth0Provider
中指定的loginUrl
和profileUrl
之前:
// _app.jsxfunction App({ Component, pageProps }) { return (<UserProvider loginUrl="/foo/api/auth/login" profileUrl="/foo/api/auth/me"> <Component {...pageProps} /></UserProvider> );}
此外,任何登入或登出的連結都應包含basePath
:
<a href="/foo/api/auth/login">登入</a><br /><a href="/foo/api/auth/logout">登出</a>
您應該配置 baseUrl (或AUTH0_BASE_URL
環境變數)。例如:
# .env.localAUTH0_BASE_URL=http://localhost:3000/foo
對於受伺服器端 withPageAuthRequired 保護的任何頁面,如有必要,您應該根據basePath
和locale
更新returnTo
參數。
// ./pages/my-ssr-page.jsxexport 預設 MySsrPage = () => <></>;const getFullReturnTo = (ctx) => { // TODO: 基於 ctx.resolvedUrl, ctx.locale 實作 getFullReturnTo // 以及你的 next.config.js 的 basePath 和 i18n 設定。 return '/foo/en-US/my-ssr-page';};export const getServerSideProps = (ctx) => { const returnTo = getFullReturnTo(ctx.req); return withPageAuthRequired({ returnTo })(ctx);};
我們還提供了 Auth0 React SDK,auth0-react,它可能適合您的 Next.js 應用程式。
auth0-react
所使用的 SPA 安全模型與該 SDK 使用的 Web 應用程式安全模型不同。簡而言之,此 SDK 使用 cookie 會話保護頁面和 API 路由(請參閱「Cookie 和安全性」)。像auth0-react
這樣的 SPA 庫將直接在瀏覽器中儲存使用者的 ID 令牌和存取令牌,並使用它們直接存取外部 API。
您應該了解這兩種型號的安全隱患。但是,如果您滿足以下任一場景,auth0-react可能更適合您的需求:
您正在將靜態 HTML 匯出與 Next.js 結合使用。
您不需要在伺服器端渲染期間存取使用者資料。
您希望取得存取權杖並直接從前端層呼叫外部 API,而不是使用 Next.js API 路由作為代理程式來呼叫外部 API。
預設情況下,SDK 會建立並管理一個在應用程式的生命週期內運行的單例實例。測試應用程式時,您可能需要重設此實例,以便其狀態不會在測試之間洩漏。
如果您使用 Jest,我們建議在每次測試後使用jest.resetModules()
。或者,您可以考慮建立自己的 SDK 實例,以便可以在測試之間重新建立它。
對於端到端測試,請查看我們如何使用模擬 OIDC 提供者。
對於部署,請查看我們如何將範例應用程式部署到 Vercel。
我們感謝對此存儲庫的反饋和貢獻!在開始之前,請閱讀以下內容:
Auth0 的一般貢獻指南
Auth0 的行為準則指南
本倉庫的貢獻指南
請不要在公共 GitHub 問題追蹤器上報告安全漏洞。負責任的揭露計劃詳細說明了揭露安全問題的程序。
Auth0是一個易於實施、適應性強的身份驗證和授權平台。要了解更多信息,請查看為什麼選擇 Auth0?
該專案已獲得 MIT 許可。有關詳細信息,請參閱許可證文件。