Auth0 Next.js SDK عبارة عن مكتبة لتنفيذ مصادقة المستخدم في تطبيقات Next.js.
الوثائق - البدء - مرجع واجهة برمجة التطبيقات - التعليقات
QuickStart- دليلنا لإضافة Auth0 إلى تطبيق Next.js الخاص بك.
الأسئلة الشائعة - الأسئلة المتداولة حول nextjs-auth0.
أمثلة - الكثير من الأمثلة لحالات الاستخدام المختلفة.
الأمان - بعض الإشعارات الأمنية المهمة التي يجب عليك التحقق منها.
الهندسة المعمارية - نظرة عامة معمارية على SDK.
الاختبار - بعض المساعدة في اختبار تطبيق nextjs-auth0 الخاص بك.
النشر - كيف ننشر تطبيقنا النموذجي على Vercel.
موقع المستندات - استكشف موقع المستندات الخاص بنا وتعرف على المزيد حول Auth0.
باستخدام npm:
تثبيت npm @auth0/nextjs-auth0
تتطلب هذه المكتبة Node.js 16 LTS وإصدارات LTS الأحدث.
قم بإنشاء تطبيق ويب عادي في لوحة معلومات Auth0.
إذا كنت تستخدم تطبيقًا موجودًا ، فتأكد من تكوين الإعدادات التالية في تطبيق الويب العادي لديك:
انقر فوق علامة التبويب "الإعدادات" في صفحة التطبيق الخاص بك.
قم بالتمرير لأسفل وانقر على الرابط "إظهار الإعدادات المتقدمة".
ضمن "الإعدادات المتقدمة"، انقر فوق علامة التبويب "OAuth".
تأكد من تعيين "خوارزمية التوقيع JsonWebToken" على
RS256
ومن تمكين "OIDC Conformant".
بعد ذلك، قم بتكوين عناوين URL التالية لتطبيقك ضمن قسم "معرفات URI للتطبيق" في صفحة "الإعدادات":
عناوين URL المسموح بها لرد الاتصال : http://localhost:3000/api/auth/callback
عناوين URL المسموح بها لتسجيل الخروج : http://localhost:3000/
قم بتدوين قيم معرف العميل وسر العميل والمجال ضمن قسم "المعلومات الأساسية". ستحتاج إلى هذه القيم في الخطوة التالية.
أنت بحاجة إلى السماح لتطبيق Next.js الخاص بك بالتواصل بشكل صحيح مع Auth0. يمكنك القيام بذلك عن طريق إنشاء ملف .env.local
ضمن دليل المشروع الجذر الخاص بك والذي يحدد قيم تكوين Auth0 الضرورية كما يلي:
# قيمة سرية طويلة تُستخدم لتشفير ملف تعريف الارتباط للجلسةAUTH0_SECRET='LONG_RANDOM_VALUE'# عنوان url الأساسي لتطبيقكAUTH0_BASE_URL='http://localhost:3000'# عنوان url لمجال المستأجر Auth0AUTH0_ISSUER_BASE_URL='https://YOUR_AUTH0_DOMAIN.auth0 .com'# المصادقة الخاصة بك0 معرف عميل التطبيق Auth0_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.
متابعة الإعداد وفقًا لجهاز التوجيه الخاص بك:
جهاز توجيه الصفحة
جهاز توجيه التطبيق
قم بإنشاء معالج مسار API ديناميكي ضمن دليل /pages/api
:
قم بإنشاء دليل auth
ضمن الدليل /pages/api/
.
قم بإنشاء ملف [auth0].js
ضمن دليل auth
المنشأ حديثًا.
سيكون المسار إلى ملف توجيه واجهة برمجة التطبيقات الديناميكي هو /pages/api/auth/[auth0].js
. قم بتعبئة هذا الملف على النحو التالي:
استيراد { HandleAuth } من '@auth0/nextjs-auth0'؛ تصدير HandleAuth الافتراضي ()؛
قم بلف مكون pages/_app.js
الخاص بك بمكون UserProvider
:
// الصفحات/_app.jsimport الرد من 'react'؛import { UserProvider } من '@auth0/nextjs-auth0/client'؛ تصدير الوظيفة الافتراضية App({ Component, pageProps }) { العودة (<UserProvider> <Component {...pageProps} /></UserProvider> );}
يمكنك الآن تحديد ما إذا كان المستخدم قد تمت المصادقة عليه عن طريق التحقق من تعريف كائن user
الذي تم إرجاعه بواسطة الخطاف useUser()
. يمكنك أيضًا تسجيل الدخول أو تسجيل الخروج لمستخدميك من طبقة الواجهة الأمامية لتطبيق Next.js الخاص بك عن طريق إعادة توجيههم إلى المسار المناسب الذي تم إنشاؤه تلقائيًا:
// pages/index.jsimport { useUser } from '@auth0/nextjs-auth0/client'؛ تصدير الوظيفة الافتراضية Index() { const { user, error, isLoading } = useUser(); إذا (isLoading) يُرجع <div>جارٍ التحميل...</div>; إذا (خطأ) يُرجع <div>{error.message</div>؛ إذا (مستخدم) {return ( <div>مرحبًا {user.name}! <a href="/api/auth/logout">تسجيل الخروج</a> </div>); } return <a href="/api/auth/login">تسجيل الدخول</a>;}
قد تقترح قواعد الفحص التالية استخدام مكون
Link
بدلاً من علامة الربط. يهدف مكونLink
إلى إجراء انتقالات من جانب العميل بين الصفحات. نظرًا لأن الروابط تشير إلى مسار واجهة برمجة التطبيقات (API) وليس إلى صفحة، فيجب عليك الاحتفاظ بها كعلامات ربط.
تحقق من استخدام SDK هذا مع مكونات React Server قبل المتابعة.
أنشئ معالج مسار واجهة برمجة التطبيقات الديناميكي الشامل ضمن دليل /app/api
(بالمعنى الدقيق للكلمة، لا تحتاج إلى وضع مسارات واجهة برمجة التطبيقات ضمن /api
ولكننا نحافظ على التقليد من أجل البساطة):
قم بإنشاء دليل api
ضمن الدليل /app/
.
قم بإنشاء دليل auth
ضمن الدليل /app/api/
الذي تم إنشاؤه حديثًا.
قم بإنشاء دليل [auth0]
ضمن دليل auth
الذي تم إنشاؤه حديثًا.
قم بإنشاء ملف route.js
ضمن الدليل [auth0]
الذي تم إنشاؤه حديثًا.
سيكون المسار إلى ملف مسار API الديناميكي الخاص بك هو /app/api/auth/[auth0]/route.js
. قم بتعبئة هذا الملف على النحو التالي:
import { HandleAuth } from '@auth0/nextjs-auth0';export const GET = HandleAuth();
UserProvider
إلى تخطيطك قم بلف مكون app/layout.js
الخاص بك بمكون UserProvider
:
// app/layout.jsimport React from 'react';import { UserProvider } from '@auth0/nextjs-auth0/client'; تصدير الوظيفة الافتراضية App({ children }) { العودة (<UserProvider> <body>{children}</body></UserProvider> );}
يمكنك الآن تحديد ما إذا كان المستخدم قد تمت المصادقة عليه عن طريق التحقق من تعريف كائن user
الذي تم إرجاعه بواسطة الخطاف useUser()
. يمكنك أيضًا تسجيل الدخول أو تسجيل الخروج لمستخدميك من طبقة الواجهة الأمامية لتطبيق Next.js الخاص بك عن طريق إعادة توجيههم إلى المسار المناسب الذي تم إنشاؤه تلقائيًا:
// pages/index.js'use client';import { useUser } from '@auth0/nextjs-auth0/client';تصدير الوظيفة الافتراضية Index() { const { user, error, isLoading } = useUser(); إذا (isLoading) يُرجع <div>جارٍ التحميل...</div>; إذا (خطأ) يُرجع <div>{error.message</div>؛ إذا (مستخدم) {return ( <div>مرحبًا {user.name}! <a href="/api/auth/logout">تسجيل الخروج</a> </div>); } return <a href="/api/auth/login">تسجيل الدخول</a>;}
قد تقترح قواعد الفحص التالية استخدام مكون
Link
بدلاً من علامة الربط. يهدف مكونLink
إلى إجراء انتقالات من جانب العميل بين الصفحات. نظرًا لأن الروابط تشير إلى مسار واجهة برمجة التطبيقات (API) وليس إلى صفحة، فيجب عليك الاحتفاظ بها كعلامات ربط.
لا يمكن لمكونات الخادم الموجودة في دليل التطبيقات (بما في ذلك الصفحات والتخطيطات) الكتابة إلى ملف تعريف الارتباط.
إذا كنت تعتمد فقط على مكونات الخادم لقراءة جلستك وتحديثها، فيجب أن تكون على دراية بما يلي:
إذا كانت لديك جلسة متجددة (الإعداد الافتراضي لمجموعة SDK هذه)، فلن يتم تحديث انتهاء الصلاحية عندما يزور المستخدم موقعك. لذلك قد تنتهي صلاحية الجلسة في وقت أقرب مما تتوقع (يمكنك استخدام withMiddlewareAuthRequired
للتخفيف من ذلك).
إذا قمت بتحديث رمز الوصول، فلن يستمر رمز الوصول الجديد في الجلسة. لذا فإن المحاولات اللاحقة للحصول على رمز الوصول ستؤدي دائمًا إلى تحديث رمز الوصول منتهي الصلاحية في الجلسة.
إذا قمت بإجراء أي تحديثات أخرى للجلسة، فلن تستمر بين الطلبات.
يمكن كتابة ملف تعريف الارتباط من البرامج الوسيطة ومعالجات المسار وإجراءات الخادم.
للحصول على أمثلة شاملة أخرى، راجع مستند EXAMPLES.md.
import * from @auth0/nextjs-auth0
import * from @auth0/nextjs-auth0/edge
خيارات التكوين ومتغيرات البيئة
initAuth0
HandleAuth
HandleLogin
HandleCallback
HandleLogout
HandleProfile
معApiAuthRequired
معPageAuthRequired
getSession
updateSession
getAccessToken
معMiddlewareAuthRequired (Edge فقط)
import * from @auth0/nextjs-auth0/client
مزود المستخدم
useUser
معPageAuthRequired
import * from @auth0/nextjs-auth0/testing
createSessionCookie
تفضل بزيارة مستندات API التي تم إنشاؤها تلقائيًا للحصول على مزيد من التفاصيل
سيتم تعيين جميع ملفات تعريف الارتباط على HttpOnly, SameSite=Lax
وسيتم تعيينها على Secure
إذا كان AUTH0_BASE_URL
الخاص بالتطبيق هو https
.
سيتأكد إعداد HttpOnly
من أن JavaScript من جانب العميل غير قادر على الوصول إلى ملف تعريف الارتباط لتقليل سطح الهجوم لهجمات XSS.
سيساعد إعداد SameSite=Lax
على تخفيف هجمات CSRF. تعرف على المزيد حول SameSite من خلال قراءة منشور المدونة "التغييرات القادمة في سلوك المتصفح: ما يحتاج المطورون إلى معرفته".
سيعرض العديد من موفري خدمات الاستضافة تخزين المحتوى الخاص بك مؤقتًا على الحافة من أجل تقديم البيانات للمستخدمين في أسرع وقت ممكن. على سبيل المثال، سيقوم Vercel بتخزين المحتوى الخاص بك مؤقتًا على شبكة Vercel Edge لجميع المحتوى الثابت والوظائف بدون خادم إذا قمت بتوفير رؤوس التخزين المؤقت اللازمة في استجابتك.
إنها فكرة سيئة عمومًا تخزين أي استجابة تتطلب مصادقة مؤقتًا، حتى إذا كان محتوى الاستجابة يبدو آمنًا للتخزين المؤقت، فقد تكون هناك بيانات أخرى في الاستجابة ليست كذلك.
يوفر SDK هذا جلسة متجددة بشكل افتراضي، مما يعني أن أي استجابة تقرأ الجلسة سيكون لها رأس Set-Cookie
لتحديث انتهاء صلاحية ملف تعريف الارتباط. يقوم Vercel وموفرو الاستضافة الآخرون المحتملون بتضمين رأس Set-Cookie
في الاستجابة المخزنة مؤقتًا، لذلك حتى إذا كنت تعتقد أنه يمكن تخزين محتوى الاستجابة مؤقتًا بشكل عام، فإن رأس Set-Cookie
للاستجابات لا يمكن ذلك.
تحقق من قواعد التخزين المؤقت لموفر الاستضافة الخاص بك، ولكن بشكل عام لا ينبغي عليك أبدًا تخزين الاستجابات التي تتطلب مصادقة أو حتى لمس الجلسة للتحقق من المصادقة (على سبيل المثال عند استخدام withApiAuthRequired
أو withPageAuthRequired
أو حتى getSession
أو getAccessToken
فقط).
قد تحتوي الأخطاء التي تأتي من Auth0 في رد الاتصال redirect_uri
على إدخال المستخدم المنعكس عبر error
OpenID Connect ومعلمة الاستعلام error_description
. ولهذا السبب، نقوم ببعض عمليات التهرب الأساسية من خصائص message
error
و error_description
الخاصة بـ IdentityProviderError
.
لكن، إذا كتبت معالج الأخطاء الخاص بك، فلا ينبغي عليك عرض message
الخطأ أو خصائص error
و error_description
دون استخدام محرك القوالب الذي سيهرب منها بشكل صحيح لسياقات HTML الأخرى أولاً.
باستخدام Next.js، يمكنك نشر تطبيق Next.js ضمن مسار فرعي للمجال باستخدام المسار الأساسي وخدمة المسارات الدولية (i18n) باستخدام التوجيه الدولي.
إذا كنت تستخدم هذه الميزات، فستتغير عناوين URL الخاصة بتطبيقك وبالتالي ستتغير عناوين URL إلى مسارات nextjs-auth0. لاستيعاب ذلك، توجد أماكن مختلفة في SDK يمكنك من خلالها تخصيص عنوان url.
على سبيل المثال، إذا كان basePath: '/foo'
فيجب عليك إلحاق هذا مسبقًا بـ loginUrl
و profileUrl
المحددين في Auth0Provider
:
// _app.jsxfunction App({ Component,pageProps }) { return (<UserProviderloginUrl="/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، يجب عليك تحديث معلمة returnTo
اعتمادًا على basePath
والإعدادات locale
إذا لزم الأمر.
// ./pages/my-ssr-page.jsxexport default MySsrPage = () => <></>;const getFullReturnTo = (ctx) => { // TODO: تنفيذ getFullReturnTo بناءً على ctx.resolvedUrl، ctx.locale // وإعدادات basePath وi18n الخاصة بـ next.config.js. return '/foo/en-US/my-ssr-page';};تصدير const getServerSideProps = (ctx) => { const returnTo = getFullReturnTo(ctx.req); return withPageAuthRequired({ returnTo })(ctx);};
نوفر أيضًا Auth0 React SDK، auth0-react، والذي قد يكون مناسبًا لتطبيق Next.js الخاص بك.
يختلف نموذج أمان SPA الذي يستخدمه auth0-react
عن نموذج أمان تطبيق الويب الذي يستخدمه SDK هذا. باختصار، يقوم SDK هذا بحماية الصفحات ومسارات واجهة برمجة التطبيقات (API) من خلال جلسة ملفات تعريف الارتباط (راجع "ملفات تعريف الارتباط والأمان"). ستقوم مكتبة SPA مثل auth0-react
بتخزين رمز معرف المستخدم ورمز الوصول مباشرة في المتصفح واستخدامها للوصول إلى واجهات برمجة التطبيقات الخارجية مباشرة.
يجب أن تكون على دراية بالآثار الأمنية لكلا النموذجين. ومع ذلك، قد يكون auth0-react أكثر ملاءمة لاحتياجاتك إذا استوفيت أيًا من السيناريوهات التالية:
أنت تستخدم تصدير HTML ثابت مع Next.js.
لا تحتاج إلى الوصول إلى بيانات المستخدم أثناء العرض من جانب الخادم.
تريد الحصول على رمز الوصول واستدعاء واجهات برمجة التطبيقات الخارجية مباشرةً من طبقة الواجهة الأمامية بدلاً من استخدام مسارات واجهة برمجة تطبيقات Next.js كوكيل لاستدعاء واجهات برمجة التطبيقات الخارجية.
افتراضيًا، يقوم SDK بإنشاء وإدارة مثيل فردي ليتم تشغيله طوال عمر التطبيق. عند اختبار التطبيق الخاص بك، قد تحتاج إلى إعادة تعيين هذا المثيل، بحيث لا تتسرب حالته بين الاختبارات.
إذا كنت تستخدم Jest، فنوصي باستخدام jest.resetModules()
بعد كل اختبار. وبدلاً من ذلك، يمكنك النظر في إنشاء مثيل خاص بك من SDK، بحيث يمكن إعادة إنشائه بين الاختبارات.
بالنسبة للاختبارات الشاملة، قم بإلقاء نظرة على كيفية استخدامنا لموفر OIDC وهمي.
للنشر، قم بإلقاء نظرة على كيفية نشر تطبيقنا النموذجي على Vercel.
نحن نقدر ردود الفعل والمساهمة في هذا الريبو! قبل البدء، يرجى قراءة ما يلي:
إرشادات المساهمة العامة لـ Auth0
إرشادات قواعد السلوك الخاصة بـ Auth0
دليل مساهمة الريبو هذا
يرجى عدم الإبلاغ عن الثغرات الأمنية في متتبع مشكلات GitHub العام. يوضح برنامج الإفصاح المسؤول تفاصيل إجراءات الكشف عن المشكلات الأمنية.
Auth0 عبارة عن منصة مصادقة وترخيص سهلة التنفيذ وقابلة للتكيف. لمعرفة المزيد الخروج لماذا Auth0؟
هذا المشروع مرخص بموجب ترخيص MIT. راجع ملف الترخيص لمزيد من المعلومات.