میتوانید به کاربران خود اجازه دهید بااستفاده از Apple ID خود با Firebase اصالتسنجی کنند بااستفاده از کیت توسعه نرمافزار Firebase برای انجام جریان ورود به سیستم OAuth 2.0 سرتاسر.
قبل از شروع
برای ورود به سیستم کاربران بااستفاده از Apple، ابتدا «ورود به سیستم با Apple» را در سایت توسعهدهنده Apple پیکربندی کنید، سپس Apple را بهعنوان ارائهدهنده ورود به سیستم برای پروژه Firebase خود فعال کنید.
به «برنامه توسعهدهندگان Apple» بپیوندید
«ورود به سیستم با Apple» فقط توسط اعضای برنامه توسعهدهندگان Apple قابل پیکربندی است.
پیکربندی «ورود به سیستم با Apple»
در سایت توسعهدهنده Apple، مراحل زیر را انجام دهید:
-
وبسایتتان را با برنامهتان مرتبط کنید، همانطور که در بخش اول پیکربندی «ورود به سیستم با Apple» برای وب توضیح داده شده است. وقتی درخواست شد، نشانی وب زیر را بهعنوان «نشانی وب بازگشت» ثبت کنید:
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 ID ناشناسسازیشده یا برعکس.
- پیوند دادن شماره تلفن به Apple ID ناشناسسازیشده یا برعکس
- اعتبار اجتماعی غیرگمنام (Facebook، Google، و غیره) را به Apple ID گمنامشده پیوند دهید یا برعکس.
فهرست بالا کامل نیست. برای اطمینان از اینکه برنامهتان الزامات Apple را برآورده میکند، به «قرارداد پروانه برنامه توسعهدهندگان Apple» در بخش «عضویت» حساب توسعهدهندهتان مراجعه کنید.
جریان ورود به سیستم را با کیت توسعه نرمافزار Firebase مدیریت کنید
اگر برنامه وب میسازید، سادهترین راه برای اصالتسنجی کاربران با Firebase بااستفاده از حسابهای Apple آنها این است که کل جریان ورود به سیستم را با کیت توسعه نرمافزار Firebase JavaScript مدیریت کنید.
برای مدیریت جریان ورود به سیستم با کیت توسعه نرمافزار جاوا اسکریپت در Firebase، این مراحل را دنبال کنید:
بااستفاده از شناسه ارائهدهنده مربوطه apple.com، نمونهای از OAuthProvider ایجاد کنید.
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' });
بااستفاده از شیء ارائهدهنده OAuth، با Firebase اصالتسنجی کنید. میتوانید از کاربران بخواهید با «حسابهای 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 نشانی وب عکس ارائه نمیدهد.
همچنین، وقتی کاربر انتخاب میکند ایمیلش را با برنامه همرسانی نکند، 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 وقتی کاربران با «ورود به سیستم با Apple» ایجاد میشوند نشانهای کاربر را ذخیره نمیکند، باید از کاربر بخواهید قبلاز باطل کردن نشان و حذف حسابش دوباره به سیستم وارد شود.
سپس، کد دسترسی Apple OAuth را از
OAuthCredentialدریافت کنید، و از آن برای فراخوانیrevokeAccessToken(auth, token)برای لغو کد دسترسی Apple OAuth استفاده کنید.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 ID کاربر را دریافت کنید. این کار را میتوانید به چندین روش انجام دهید. برای مثال، اگر برنامه Node.js شما دارای میانای مرورگر باشد:
در باطن خود، یک رشته تصادفی («nonce») تولید کنید و درهمسازی 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');
در صفحه ورود به سیستم، مقدار یکبارمصرف درهمسازیشده را در پیکربندی «ورود به سیستم با 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 ID از پاسخ احراز هویت POSTed در سمت سرور:
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 ID کاربر، از آن برای ساختن شیء «اطلاعات اعتباری» استفاده کنید و سپس کاربر را با اطلاعات اعتباری به سیستم وارد کنید:
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. });