يمكنك السماح للمستخدمين بالمصادقة باستخدام Firebase من خلال حساباتهم على Apple عن طريق استخدام حزمة تطوير البرامج (SDK) من Firebase لتنفيذ عملية تسجيل الدخول الكاملة باستخدام بروتوكول OAuth 2.0.
قبل البدء
لتسجيل دخول المستخدمين باستخدام Apple، عليك أولاً إعداد ميزة "تسجيل الدخول باستخدام Apple" على موقع مطوّري Apple الإلكتروني، ثم تفعيل Apple كموفّر خدمة تسجيل الدخول لمشروعك على Firebase.
الانضمام إلى "برنامج المطوّرين من Apple"
لا يمكن إعداد ميزة "تسجيل الدخول باستخدام حساب على Apple" إلا من خلال أعضاء برنامج Apple Developer.
ضبط ميزة "تسجيل الدخول باستخدام حساب على Apple"
في موقع مطوّري Apple، اتّبِع الخطوات التالية:
-
اربط موقعك الإلكتروني بتطبيقك كما هو موضّح في القسم الأول من مقالة إعداد ميزة "تسجيل الدخول باستخدام Apple" على الويب. عندما يُطلب منك ذلك، سجِّل عنوان URL التالي كعنوان URL للرجوع:
https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler
يمكنك الحصول على رقم تعريف مشروعك على Firebase من صفحة إعداداتFirebase وحدة التحكّم.
عند الانتهاء، سجِّل رقم تعريف الخدمة الجديد الذي ستحتاج إليه في القسم التالي.
- إنشاء مفتاح خاص لتطبيق "تسجيل الدخول باستخدام Apple" ستحتاج إلى المفتاح الخاص الجديد ورقم تعريف المفتاح في القسم التالي.
-
إذا كنت تستخدم أيًا من ميزات Firebase Authentication التي ترسل رسائل إلكترونية إلى المستخدمين، بما في ذلك تسجيل الدخول باستخدام رابط في البريد الإلكتروني، وإثبات ملكية عنوان البريد الإلكتروني، وإلغاء تغيير الحساب، وغيرها، عليك إعداد خدمة ترحيل البريد الإلكتروني الخاص من Apple وتسجيل
noreply@YOUR_FIREBASE_PROJECT_ID.firebaseapp.com
(أو نطاق نموذج البريد الإلكتروني المخصّص) لكي تتمكّن Apple من ترحيل الرسائل الإلكترونية التي ترسلها Firebase Authentication إلى عناوين بريد إلكتروني مجهولة الهوية من Apple.
تفعيل Apple كموفّر لخدمة تسجيل الدخول
- أضِف Firebase إلى مشروعك.
- في وحدة تحكّم Firebase، افتح قسم المصادقة. في علامة التبويب طريقة تسجيل الدخول، فعِّل موفّر Apple. حدِّد معرّف الخدمة الذي أنشأته في القسم السابق. في قسم إعدادات عملية الحصول على رمز OAuth، حدِّد أيضًا معرّف فريق Apple والمفتاح الخاص ومعرّف المفتاح اللذين أنشأتهما في القسم السابق.
الالتزام بمتطلبات Apple بشأن البيانات المخفية الهوية
يمنح خيار "تسجيل الدخول باستخدام Apple" المستخدمين إمكانية إخفاء هوية بياناتهم، بما في ذلك عنوان بريدهم الإلكتروني، عند تسجيل الدخول. يحصل المستخدمون الذين يختارون هذا الخيار على عناوين بريد إلكتروني تتضمّن النطاق privaterelay.appleid.com
. عند استخدام ميزة "تسجيل الدخول باستخدام Apple" في تطبيقك، عليك الالتزام بأي سياسات أو بنود مطوّرين سارية من Apple بشأن معرّفات Apple المجهولة الهوية هذه.
ويشمل ذلك الحصول على موافقة المستخدمين المطلوبة قبل ربط أي معلومات شخصية تحدد الهوية مباشرةً بمعرّف Apple مجهول الهوية. عند استخدام "مصادقة Firebase"، قد يشمل ذلك الإجراءات التالية:
- ربط عنوان بريد إلكتروني بمعرّف Apple مخفيّ الهوية أو العكس
- ربط رقم هاتف بمعرّف Apple مخفي الهوية أو العكس
- ربط بيانات اعتماد اجتماعية غير مجهولة الهوية (Facebook أو Google أو غير ذلك) بمعرّف Apple مجهول الهوية أو العكس
يُرجى العِلم أنّ القائمة أعلاه ليست شاملة. يُرجى الرجوع إلى اتفاقية ترخيص برنامج Apple للمطوّرين في قسم "الاشتراك" ضمن حساب المطوّر للتأكّد من أنّ تطبيقك يستوفي متطلبات Apple.
التعامل مع عملية تسجيل الدخول باستخدام حزمة تطوير البرامج (SDK) من Firebase
إذا كنت بصدد إنشاء تطبيق ويب، فإنّ أسهل طريقة لمصادقة المستخدمين باستخدام Firebase من خلال حساباتهم على Apple هي التعامل مع عملية تسجيل الدخول بأكملها باستخدام حزمة تطوير البرامج (SDK) من Firebase JavaScript.
لإدارة عملية تسجيل الدخول باستخدام حزمة تطوير البرامج JavaScript من Firebase، اتّبِع الخطوات التالية:
أنشئ مثيلاً من OAuthProvider باستخدام معرّف مقدّم الخدمة apple.com المناسب.
Web
import { OAuthProvider } from "firebase/auth"; const provider = new OAuthProvider('apple.com');
Web
var provider = new firebase.auth.OAuthProvider('apple.com');
اختياري: حدِّد نطاقات إضافية لبروتوكول OAuth 2.0 تتجاوز النطاقات التلقائية التي تريد طلبها من موفّر المصادقة.
Web
provider.addScope('email'); provider.addScope('name');
Web
provider.addScope('email'); provider.addScope('name');
عند تفعيل خيار حساب واحد لكل عنوان بريد إلكتروني تلقائيًا، يطلب Firebase نطاقات البريد الإلكتروني والاسم. في حال تغيير هذا الإعداد إلى حسابات متعدّدة لكل عنوان بريد إلكتروني، لن تطلب Firebase أي نطاقات من Apple إلا إذا حدّدتها.
اختياري: إذا كنت تريد عرض شاشة تسجيل الدخول من Apple بلغة أخرى غير الإنجليزية، اضبط المَعلمة
locale
. راجِع مستندات "تسجيل الدخول باستخدام Apple" لمعرفة اللغات المتوافقة.Web
provider.setCustomParameters({ // Localize the Apple authentication screen in French. locale: 'fr' });
Web
provider.setCustomParameters({ // Localize the Apple authentication screen in French. locale: 'fr' });
يمكنك المصادقة باستخدام Firebase من خلال عنصر موفّر OAuth. يمكنك أن تطلب من المستخدمين تسجيل الدخول باستخدام حسابات Apple الخاصة بهم إما عن طريق فتح نافذة منبثقة أو عن طريق إعادة التوجيه إلى صفحة تسجيل الدخول. يُفضّل استخدام طريقة إعادة التوجيه على الأجهزة الجوّالة.
لتسجيل الدخول باستخدام نافذة منبثقة، اتّصِل بالرقم
signInWithPopup()
:Web
import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth"; const auth = getAuth(); signInWithPopup(auth, provider) .then((result) => { // The signed-in user info. const user = result.user; // Apple credential const credential = OAuthProvider.credentialFromResult(result); const accessToken = credential.accessToken; const idToken = credential.idToken; // IdP data available using getAdditionalUserInfo(result) // ... }) .catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.customData.email; // The credential that was used. const credential = OAuthProvider.credentialFromError(error); // ... });
Web
firebase .auth() .signInWithPopup(provider) .then((result) => { /** @type {firebase.auth.OAuthCredential} */ var credential = result.credential; // The signed-in user info. var user = result.user; // You can also get the Apple OAuth Access and ID Tokens. var accessToken = credential.accessToken; var idToken = credential.idToken; // IdP data available using getAdditionalUserInfo(result) // ... }) .catch((error) => { // Handle Errors here. var errorCode = error.code; var errorMessage = error.message; // The email of the user's account used. var email = error.email; // The firebase.auth.AuthCredential type that was used. var credential = error.credential; // ... });
لتسجيل الدخول من خلال إعادة التوجيه إلى صفحة تسجيل الدخول، اتّصِل بالرقم
signInWithRedirect()
:
اتّبِع أفضل الممارسات عند استخدام
signInWithRedirect
أوlinkWithRedirect
أوreauthenticateWithRedirect
.Web
import { getAuth, signInWithRedirect } from "firebase/auth"; const auth = getAuth(); signInWithRedirect(auth, provider);
Web
firebase.auth().signInWithRedirect(provider);
بعد أن يكمل المستخدم عملية تسجيل الدخول ويعود إلى الصفحة، يمكنك الحصول على نتيجة تسجيل الدخول من خلال استدعاء
getRedirectResult()
:Web
import { getAuth, getRedirectResult, OAuthProvider } from "firebase/auth"; // Result from Redirect auth flow. const auth = getAuth(); getRedirectResult(auth) .then((result) => { const credential = OAuthProvider.credentialFromResult(result); if (credential) { // You can also get the Apple OAuth Access and ID Tokens. const accessToken = credential.accessToken; const idToken = credential.idToken; } // The signed-in user info. const user = result.user; }) .catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.customData.email; // The credential that was used. const credential = OAuthProvider.credentialFromError(error); // ... });
Web
// Result from Redirect auth flow. firebase .auth() .getRedirectResult() .then((result) => { if (result.credential) { /** @type {firebase.auth.OAuthCredential} */ var credential = result.credential; // You can get the Apple OAuth Access and ID Tokens. var accessToken = credential.accessToken; var idToken = credential.idToken; // IdP data available in result.additionalUserInfo.profile. // ... } // The signed-in user info. var user = result.user; }) .catch((error) => { // Handle Errors here. var errorCode = error.code; var errorMessage = error.message; // The email of the user's account used. var email = error.email; // The firebase.auth.AuthCredential type that was used. var credential = error.credential; // ... });
يمكنك أيضًا رصد الأخطاء ومعالجتها من خلال هذه الأداة. للاطّلاع على قائمة برموز الأخطاء، يُرجى الرجوع إلى مرجع واجهة برمجة التطبيقات.
على عكس موفّري الخدمات الآخرين الذين تتوافق معهم خدمة Firebase Auth، لا توفّر Apple عنوان URL للصورة.
عندما يختار المستخدم عدم مشاركة عنوان بريده الإلكتروني مع التطبيق، توفّر Apple عنوان بريد إلكتروني فريدًا لهذا المستخدم (بالتنسيق
xyz@privaterelay.appleid.com
)، وتشاركه مع تطبيقك. وإذا كنت قد أعددت خدمة الترحيل عبر البريد الإلكتروني الخاص، تعيد Apple توجيه الرسائل الإلكترونية المُرسَلة إلى العنوان المجهول إلى عنوان البريد الإلكتروني الحقيقي للمستخدم.تشارك Apple معلومات المستخدمين، مثل الاسم المعروض، مع التطبيقات فقط عند تسجيل المستخدم الدخول لأول مرة. يخزّن Firebase عادةً الاسم المعروض عند تسجيل دخول المستخدم لأول مرة باستخدام Apple، ويمكنك الحصول عليه باستخدام
firebase.auth().currentUser.displayName
. ومع ذلك، إذا سبق لك استخدام Apple لتسجيل دخول مستخدم إلى التطبيق بدون استخدام Firebase، لن يقدّم Apple إلى Firebase اسم المستخدم المعروض.
إعادة المصادقة وربط الحساب
يمكن استخدام النمط نفسه مع reauthenticateWithPopup()
وreauthenticateWithRedirect()
، ويمكنك استخدامهما لاسترداد بيانات اعتماد جديدة للعمليات الحسّاسة التي تتطلّب تسجيل دخول حديث:
Web
import { getAuth, reauthenticateWithPopup, OAuthProvider } from "firebase/auth"; // Result from Redirect auth flow. const auth = getAuth(); const provider = new OAuthProvider('apple.com'); reauthenticateWithPopup(auth.currentUser, provider) .then((result) => { // User is re-authenticated with fresh tokens minted and can perform // sensitive operations like account deletion, or updating their email // address or password. // The signed-in user info. const user = result.user; // You can also get the Apple OAuth Access and ID Tokens. const credential = OAuthProvider.credentialFromResult(result); const accessToken = credential.accessToken; const idToken = credential.idToken; // ... }) .catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.customData.email; // The credential that was used. const credential = OAuthProvider.credentialFromError(error); // ... });
Web
const provider = new firebase.auth.OAuthProvider('apple.com'); firebase .auth() .currentUser .reauthenticateWithPopup(provider) .then((result) => { // User is re-authenticated with fresh tokens minted and can perform // sensitive operations like account deletion, or updating their email // address or password. /** @type {firebase.auth.OAuthCredential} */ var credential = result.credential; // The signed-in user info. var user = result.user; // You can also get the Apple OAuth Access and ID Tokens. var accessToken = credential.accessToken; var idToken = credential.idToken; // IdP data available in result.additionalUserInfo.profile. // ... }) .catch((error) => { // Handle Errors here. var errorCode = error.code; var errorMessage = error.message; // The email of the user's account used. var email = error.email; // The firebase.auth.AuthCredential type that was used. var credential = error.credential; // ... });
ويمكنك استخدام linkWithPopup()
وlinkWithRedirect()
لربط مقدّمي خدمات هوية مختلفين بالحسابات الحالية.
يُرجى العِلم أنّ Apple تفرض عليك الحصول على موافقة صريحة من المستخدمين قبل ربط حساباتهم على Apple ببيانات أخرى.
على سبيل المثال، لربط حساب على Facebook بحساب Firebase الحالي، استخدِم رمز الدخول الذي حصلت عليه من خلال تسجيل دخول المستخدم إلى Facebook:
Web
import { getAuth, linkWithPopup, FacebookAuthProvider } from "firebase/auth"; const auth = getAuth(); const provider = new FacebookAuthProvider(); provider.addScope('user_birthday'); // Assuming the current user is an Apple user linking a Facebook provider. linkWithPopup(auth.currentUser, provider) .then((result) => { // Facebook credential is linked to the current Apple user. // ... // The user can now sign in to the same account // with either Apple or Facebook. }) .catch((error) => { // Handle error. });
Web
const provider = new firebase.auth.FacebookAuthProvider(); provider.addScope('user_birthday'); // Assuming the current user is an Apple user linking a Facebook provider. firebase.auth().currentUser.linkWithPopup(provider) .then((result) => { // Facebook credential is linked to the current Apple user. // Facebook additional data available in result.additionalUserInfo.profile, // Additional Facebook OAuth access token can also be retrieved. // result.credential.accessToken // The user can now sign in to the same account // with either Apple or Facebook. }) .catch((error) => { // Handle error. });
المصادقة باستخدام Firebase في إضافة Chrome
إذا كنت بصدد إنشاء تطبيق إضافة Chrome، يمكنك الاطّلاع على دليل المستندات خارج الشاشة.
يُرجى العِلم أنّه يجب إثبات ملكية النطاق المخصّص لدى Apple بالطريقة نفسها التي يتم بها إثبات ملكية النطاق التلقائي firebaseapp.com:
http://auth.custom.example.com/.well-known/apple-developer-domain-association.txt
إبطال الرمز المميز
تشترط Apple أن تتيح التطبيقات التي تتيح إنشاء الحسابات للمستخدمين بدء عملية حذف حساباتهم من داخل التطبيق، كما هو موضّح في إرشادات مراجعة App Store.
لاستيفاء هذا الشرط، اتّبِع الخطوات التالية:
تأكَّد من ملء قسمَي معرّف الخدمات وإعدادات عملية الحصول على رمز OAuth في إعدادات مقدّم خدمة "تسجيل الدخول باستخدام Apple"، كما هو موضّح في قسم إعداد "تسجيل الدخول باستخدام Apple".
بما أنّ Firebase لا يخزّن رموز المستخدمين المميزة عند إنشاء حسابات باستخدام Sign in with Apple، عليك أن تطلب من المستخدم تسجيل الدخول مرة أخرى قبل إبطال الرمز المميز وحذف الحساب.
بعد ذلك، احصل على رمز الدخول المميز عبر OAuth من Apple من
OAuthCredential
، واستخدِمه لاستدعاءrevokeAccessToken(auth, token)
لإبطال رمز الدخول المميز عبر OAuth من Apple.const provider = new OAuthProvider('apple.com'); provider.addScope('email'); provider.addScope('name'); const auth = getAuth(); signInWithPopup(auth, provider).then(result => { // Get the Apple OAuth access token. const credential = OAuthProvider.credentialFromResult(result); const accessToken = credential.accessToken; // Revoke the Apple OAuth access token. revokeAccessToken(auth, accessToken) .then(() => { // Token revoked. // Delete the user account. // ... }) .catch(error => { // An error happened. // ... }); });
أخيرًا، احذف حساب المستخدم (وجميع البيانات المرتبطة به).
إجراء متقدّم: المصادقة باستخدام Firebase في Node.js
للمصادقة باستخدام Firebase في تطبيق Node.js، اتّبِع الخطوات التالية:
سجِّل دخول المستخدم باستخدام حسابه على Apple واحصل على الرمز المميز لمعرّف Apple الخاص بالمستخدم. يمكنك تحقيق ذلك بعدة طرق. على سبيل المثال، إذا كان تطبيق Node.js يتضمّن واجهة أمامية للمتصفّح:
في الخلفية، أنشئ سلسلة عشوائية (تُعرف باسم "رقم الاستخدام لمرة واحدة") واحتسِب تجزئة SHA256 الخاصة بها. الرقم العشوائي هو قيمة تُستخدم لمرة واحدة للتحقّق من صحة عملية تبادل واحدة بين الخلفية وخوادم المصادقة التابعة لشركة Apple.
Web
const crypto = require("crypto"); const string_decoder = require("string_decoder"); // Generate a new random string for each sign-in const generateNonce = (length) => { const decoder = new string_decoder.StringDecoder("ascii"); const buf = Buffer.alloc(length); let nonce = ""; while (nonce.length < length) { crypto.randomFillSync(buf); nonce = decoder.write(buf); } return nonce.slice(0, length); }; const unhashedNonce = generateNonce(10); // SHA256-hashed nonce in hex const hashedNonceHex = crypto.createHash('sha256') .update(unhashedNonce).digest().toString('hex');
Web
const crypto = require("crypto"); const string_decoder = require("string_decoder"); // Generate a new random string for each sign-in const generateNonce = function(length) { const decoder = new string_decoder.StringDecoder("ascii"); const buf = Buffer.alloc(length); var nonce = ""; while (nonce.length < length) { crypto.randomFillSync(buf); nonce = decoder.write(buf); } return nonce.slice(0, length); }; const unhashedNonce = generateNonce(10); // SHA256-hashed nonce in hex const hashedNonceHex = crypto.createHash('sha256') .update(unhashedNonce).digest().toString('hex');
في صفحة تسجيل الدخول، حدِّد قيمة nonce المجزأة في إعدادات ميزة "تسجيل الدخول باستخدام Apple" على النحو التالي:
<script src="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"></script> <div id="appleid-signin" data-color="black" data-border="true" data-type="sign in"></div> <script> AppleID.auth.init({ clientId: YOUR_APPLE_CLIENT_ID, scope: 'name email', redirectURI: URL_TO_YOUR_REDIRECT_HANDLER, // See the next step. state: '[STATE]', // Optional value that Apple will send back to you // so you can return users to the same context after // they sign in. nonce: HASHED_NONCE // The hashed nonce you generated in the previous step. }); </script>
احصل على الرمز المميز لمعرّف Apple من ردّ المصادقة الذي تم نشره من جهة الخادم:
app.post('/redirect', (req, res) => { const savedState = req.cookies.__session; const code = req.body.code; const state = req.body.state; const appleIdToken = req.body.id_token; if (savedState !== state || !code) { res.status(403).send('403: Permission denied'); } else { // Sign in with Firebase using appleIdToken. (See next step). } });
يمكنك أيضًا الاطّلاع على ضبط صفحة الويب لاستخدام ميزة "تسجيل الدخول باستخدام Apple".
بعد الحصول على رمز مميّز لمعرّف Apple الخاص بالمستخدم، استخدِم هذا الرمز لإنشاء عنصر Credential، ثم سجِّل دخول المستخدم باستخدام بيانات الاعتماد:
Web
import { getAuth, signInWithCredential, OAuthProvider } from "firebase/auth"; const auth = getAuth(); // Build Firebase credential with the Apple ID token. const provider = new OAuthProvider('apple.com'); const authCredential = provider.credential({ idToken: appleIdToken, rawNonce: unhashedNonce, }); // Sign in with credential form the Apple user. signInWithCredential(auth, authCredential) .then((result) => { // User signed in. }) .catch((error) => { // An error occurred. If error.code == 'auth/missing-or-invalid-nonce', // make sure you're sending the SHA256-hashed nonce as a hex string // with your request to Apple. console.log(error); });
Web
// Build Firebase credential with the Apple ID token. const provider = new firebase.auth.OAuthProvider('apple.com'); const authCredential = provider.credential({ idToken: appleIdToken, rawNonce: unhashedNonce, }); // Sign in with credential form the Apple user. firebase.auth().signInWithCredential(authCredential) .then((result) => { // User signed in. }) .catch((error) => { // An error occurred. If error.code == 'auth/missing-or-invalid-nonce', // make sure you're sending the SHA256-hashed nonce as a hex string // with your request to Apple. console.log(error); });
الخطوات التالية
بعد أن يسجّل المستخدم الدخول لأول مرة، يتم إنشاء حساب مستخدم جديد وربطه ببيانات الاعتماد التي سجّل الدخول بها، أي اسم المستخدم وكلمة المرور أو رقم الهاتف أو معلومات مقدّم خدمة المصادقة. يتم تخزين هذا الحساب الجديد كجزء من مشروعك على Firebase، ويمكن استخدامه لتحديد هوية المستخدم على مستوى كل تطبيق في مشروعك، بغض النظر عن طريقة تسجيل الدخول.
-
في تطبيقاتك، الطريقة المقترَحة لمعرفة حالة المصادقة للمستخدم هي ضبط مراقب على العنصر
Auth
. يمكنك بعد ذلك الحصول على معلومات الملف الشخصي الأساسية للمستخدم من الكائنUser
. راجِع مقالة إدارة المستخدمين. في Firebase Realtime Database وCloud Storage قواعد الأمان، يمكنك الحصول على معرّف المستخدِم الفريد للمستخدِم الذي سجّل الدخول من المتغيّر
auth
، واستخدامه للتحكّم في البيانات التي يمكن للمستخدِم الوصول إليها.
يمكنك السماح للمستخدمين بتسجيل الدخول إلى تطبيقك باستخدام موفّري مصادقة متعدّدين من خلال ربط بيانات اعتماد موفّر المصادقة بحساب مستخدم حالي.
لتسجيل خروج مستخدم، اتّبِع الخطوات التالية:signOut
Web
import { getAuth, signOut } from "firebase/auth"; const auth = getAuth(); signOut(auth).then(() => { // Sign-out successful. }).catch((error) => { // An error happened. });
Web
firebase.auth().signOut().then(() => { // Sign-out successful. }).catch((error) => { // An error happened. });