شما میتوانید با استفاده از Firebase SDK برای انجام جریان ورود به سیستم OAuth 2.0 به صورت سرتاسری، به کاربران خود اجازه دهید تا با استفاده از Apple ID خود در Firebase احراز هویت کنند.
قبل از اینکه شروع کنی
برای ورود کاربران با استفاده از اپل، ابتدا ورود با اپل را در سایت توسعهدهندگان اپل پیکربندی کنید، سپس اپل را به عنوان ارائهدهنده ورود به سیستم برای پروژه Firebase خود فعال کنید.
به برنامه توسعهدهندگان اپل بپیوندید
ورود به سیستم با اپل فقط توسط اعضای برنامه توسعهدهندگان اپل قابل پیکربندی است.
پیکربندی ورود به سیستم با اپل
در سایت توسعهدهندگان اپل ، مراحل زیر را انجام دهید:
وبسایت خود را همانطور که در بخش اول پیکربندی ورود با اپل برای وب توضیح داده شده است، با برنامه خود مرتبط کنید. در صورت درخواست، URL زیر را به عنوان URL بازگشت ثبت کنید:
https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler
میتوانید شناسه پروژه Firebase خود را در اینجا پیدا کنید.
> تب عمومی کنسول Firebase . وقتی کارتان تمام شد، شناسه سرویس جدید خود را یادداشت کنید، که در بخش بعدی به آن نیاز خواهید داشت.
- با کلید خصوصی اپل، یک حساب کاربری ایجاد کنید . در بخش بعدی به کلید خصوصی جدید و شناسه کلید خود نیاز خواهید داشت.
اگر از هر یک از ویژگیهای Firebase Authentication که به کاربران ایمیل ارسال میکند، از جمله ورود از طریق لینک ایمیل، تأیید آدرس ایمیل، لغو تغییر حساب و موارد دیگر استفاده میکنید، سرویس رله ایمیل خصوصی اپل را پیکربندی کنید و
noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com(یا دامنه الگوی ایمیل سفارشی خود) را ثبت کنید تا اپل بتواند ایمیلهای ارسالی توسط Firebase Authentication را به آدرسهای ایمیل ناشناس اپل رله کند.
فعال کردن اپل به عنوان ارائه دهنده ورود به سیستم
- فایربیس را به پروژه خود اضافه کنید .
- در کنسول Firebase ، به بخش امنیت > احراز هویت بروید.
- در تب «روش ورود» ، ارائهدهنده ورود به سیستم اپل را فعال کنید. شناسه سرویس (Service ID) که در بخش قبل ایجاد کردهاید را مشخص کنید. همچنین، در بخش «پیکربندی جریان کد OAuth» ، شناسه تیم اپل و کلید خصوصی و شناسه کلید خود را که در بخش قبل ایجاد کردهاید، مشخص کنید.
مطابق با الزامات دادههای ناشناس اپل
ورود با اپل به کاربران این امکان را میدهد که هنگام ورود به سیستم، دادههای خود، از جمله آدرس ایمیل خود را ناشناس کنند. کاربرانی که این گزینه را انتخاب میکنند، آدرسهای ایمیلی با دامنه privaterelay.appleid.com دارند. هنگامی که از ورود با اپل در برنامه خود استفاده میکنید، باید از هرگونه سیاست یا شرایط توسعهدهنده مربوطه از سوی اپل در مورد این شناسههای اپل ناشناس پیروی کنید.
این شامل دریافت هرگونه رضایت کاربر قبل از مرتبط کردن هرگونه اطلاعات شخصی که مستقیماً هویت شما را مشخص میکند با یک Apple ID ناشناس میشود. هنگام استفاده از احراز هویت Firebase، این ممکن است شامل اقدامات زیر باشد:
- یک آدرس ایمیل را به یک Apple ID ناشناس یا برعکس پیوند دهید.
- یک شماره تلفن را به یک اپل آیدی ناشناس یا برعکس پیوند دهید
- یک اعتبارنامه اجتماعی غیر ناشناس (فیسبوک، گوگل و غیره) را به یک اپل آیدی ناشناس یا برعکس پیوند دهید.
لیست بالا کامل نیست. برای اطمینان از اینکه برنامه شما الزامات اپل را برآورده میکند، به توافقنامه مجوز برنامه توسعهدهندگان اپل در بخش عضویت حساب توسعهدهندگان خود مراجعه کنید.
مدیریت جریان ورود به سیستم با Firebase SDK
اگر در حال ساخت یک برنامه وب هستید، سادهترین راه برای تأیید اعتبار کاربران خود با Firebase با استفاده از حسابهای اپل آنها، مدیریت کل جریان ورود به سیستم با Firebase JavaScript SDK است.
برای مدیریت جریان ورود به سیستم با استفاده از Firebase JavaScript SDK، مراحل زیر را دنبال کنید:
با استفاده از شناسه ارائه دهنده مربوطه 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');
به طور پیشفرض، وقتی گزینهی «یک حساب کاربری برای هر آدرس ایمیل» فعال باشد، فایربیس محدودههای ایمیل و نام را درخواست میکند. اگر این تنظیم را به «چندین حساب کاربری برای هر آدرس ایمیل» تغییر دهید، فایربیس هیچ محدودهای را از اپل درخواست نمیکند، مگر اینکه شما آنها را مشخص کنید.
اختیاری: اگر میخواهید صفحه ورود به سیستم اپل را به زبانی غیر از انگلیسی نمایش دهید، پارامتر
localeرا تنظیم کنید. برای اطلاع از زبانهای پشتیبانیشده، به اسناد Sign In with 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 احراز هویت کنید. میتوانید با باز کردن یک پنجره پاپآپ یا با هدایت به صفحه ورود، کاربران خود را به ورود با حسابهای اپل خود ترغیب کنید. روش هدایت در دستگاههای تلفن همراه ترجیح داده میشود.
برای ورود به سیستم با یک پنجره پاپآپ، تابع
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; // ... });
همچنین اینجا جایی است که میتوانید خطاها را دریافت و مدیریت کنید. برای فهرستی از کدهای خطا، به مرجع API مراجعه کنید.
برخلاف سایر ارائهدهندگان پشتیبانیشده توسط Firebase Auth، اپل آدرس اینترنتی عکس ارائه نمیدهد.
همچنین، وقتی کاربر تصمیم میگیرد ایمیل خود را با برنامه به اشتراک نگذارد، اپل یک آدرس ایمیل منحصر به فرد برای آن کاربر (به شکل
xyz@privaterelay.appleid.com) فراهم میکند که آن را با برنامه شما به اشتراک میگذارد. اگر سرویس رله ایمیل خصوصی را پیکربندی کرده باشید، اپل ایمیلهای ارسالی به آدرس ناشناس را به آدرس ایمیل واقعی کاربر ارسال میکند.اپل فقط اطلاعات کاربر مانند نام نمایشی را در اولین ورود کاربر با برنامهها به اشتراک میگذارد. معمولاً Firebase نام نمایشی را در اولین ورود کاربر به Apple ذخیره میکند که میتوانید آن را با
firebase.auth().currentUser.displayNameدریافت کنید. با این حال، اگر قبلاً از Apple برای ورود کاربر به برنامه بدون استفاده از Firebase استفاده کردهاید، اپل نام نمایشی کاربر را در اختیار 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() برای پیوند دادن ارائهدهندگان هویت مختلف به حسابهای موجود استفاده کنید.
توجه داشته باشید که اپل از شما میخواهد قبل از پیوند دادن حسابهای اپل کاربران به سایر دادهها، رضایت صریح آنها را دریافت کنید.
برای مثال، برای پیوند دادن یک حساب فیسبوک به حساب فعلی Firebase، از توکن دسترسی که از ورود کاربر به فیسبوک دریافت کردهاید استفاده کنید:
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
اگر در حال ساخت یک برنامه افزونه کروم هستید، به راهنمای اسناد Offscreen مراجعه کنید.
توجه داشته باشید که شما همچنان باید دامنه سفارشی را مشابه دامنه پیشفرض firebaseapp.com با اپل تأیید کنید:
http://auth.custom.example.com/.well-known/apple-developer-domain-association.txt
ابطال توکن
اپل الزام میکند که برنامههایی که از ایجاد حساب کاربری پشتیبانی میکنند، باید به کاربران اجازه دهند حذف حساب کاربری خود را در داخل برنامه آغاز کنند، همانطور که در دستورالعملهای بررسی اپ استور توضیح داده شده است.
برای برآورده کردن این نیاز، مراحل زیر را اجرا کنید:
مطمئن شوید که بخش پیکربندی جریان کد OAuth و شناسه خدمات را در پیکربندی ارائهدهنده ورود با اپل، همانطور که در بخش پیکربندی ورود با اپل توضیح داده شده است، پر کردهاید.
از آنجایی که فایربیس توکنهای کاربر را هنگام ایجاد کاربران با ورود با اپل ذخیره نمیکند، باید قبل از لغو توکن و حذف حساب کاربری، از کاربر بخواهید دوباره وارد سیستم شود.
سپس، توکن دسترسی 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:
کاربر را با حساب کاربری اپل خود وارد سیستم کنید و توکن اپل آیدی کاربر را دریافت کنید. میتوانید این کار را از چندین طریق انجام دهید. به عنوان مثال، اگر برنامه Node.js شما دارای رابط کاربری مرورگر است:
در قسمت مدیریت سرور، یک رشته تصادفی (یک "nonce") ایجاد کنید و هش SHA256 آن را محاسبه کنید. nonce یک مقدار یکبار مصرف است که شما برای اعتبارسنجی یک رفت و برگشت بین سرور مدیریت سرور و سرورهای احراز هویت اپل از آن استفاده میکنید.
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 را مشخص کنید:
<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>دریافت توکن اپل آیدی از پاسخ احراز هویت 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 ID کاربر، از آن برای ساخت یک شیء 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 شما ذخیره میشود و میتواند برای شناسایی کاربر در هر برنامه در پروژه شما، صرف نظر از نحوه ورود کاربر، مورد استفاده قرار گیرد.
در برنامههای شما، روش پیشنهادی برای اطلاع از وضعیت احراز هویت کاربر، تنظیم یک ناظر (observer) روی شیء
Authاست. سپس میتوانید اطلاعات اولیه پروفایل کاربر را از شیءUserدریافت کنید. به بخش مدیریت کاربران (Manage Users) مراجعه کنید.در قوانین امنیتی پایگاه داده و Cloud Storage Firebase Realtime Database ، میتوانید شناسه کاربری منحصر به فرد کاربر وارد شده را از متغیر
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. });