میتوانید به کاربران خود اجازه دهید با Firebase با استفاده از ارائهدهندگان OAuth مانند Yahoo با ادغام ورود به سیستم OAuth عمومی در برنامه خود با استفاده از Firebase SDK برای انجام جریان ورود به سیستم از پایان به انتها، احراز هویت کنند.
قبل از شروع
برای ورود کاربرانی که از حساب های Yahoo استفاده می کنند، ابتدا باید یاهو را به عنوان ارائه دهنده ورود به پروژه Firebase خود فعال کنید:
- Firebase را به پروژه جاوا اسکریپت خود اضافه کنید .
- در کنسول Firebase ، بخش Auth را باز کنید.
- در زبانه روش ورود ، ارائه دهنده یاهو را فعال کنید.
- شناسه مشتری و Client Secret را از کنسول توسعه دهنده آن ارائه دهنده به پیکربندی ارائه دهنده اضافه کنید:
برای ثبت نام سرویس گیرنده Yahoo OAuth، مستندات توسعه دهنده یاهو را در مورد ثبت یک برنامه وب در Yahoo دنبال کنید.
حتماً دو مجوز OpenID Connect API را انتخاب کنید:
profile
وemail
.- هنگام ثبت برنامه در این ارائه دهندگان، مطمئن شوید که دامنه
*.firebaseapp.com
را برای پروژه خود به عنوان دامنه تغییر مسیر برای برنامه خود ثبت کنید.
- روی ذخیره کلیک کنید.
جریان ورود به سیستم را با Firebase SDK مدیریت کنید
اگر در حال ساخت یک برنامه وب هستید، ساده ترین راه برای احراز هویت کاربران خود با Firebase با استفاده از حساب های Yahoo آنها این است که کل جریان ورود به سیستم را با Firebase JavaScript SDK مدیریت کنید.
برای مدیریت جریان ورود به سیستم با Firebase JavaScript SDK، این مراحل را دنبال کنید:
با استفاده از شناسه ارائه دهنده yahoo.com یک نمونه از یک OAuthProvider ایجاد کنید.
import { OAuthProvider } from "firebase/auth"; const provider = new OAuthProvider('yahoo.com');
var provider = new firebase.auth.OAuthProvider('yahoo.com');
اختیاری : پارامترهای سفارشی OAuth اضافی را که می خواهید با درخواست OAuth ارسال کنید، مشخص کنید.
provider.setCustomParameters({ // Prompt user to re-authenticate to Yahoo. prompt: 'login', // Localize to French. language: 'fr' });
provider.setCustomParameters({ // Prompt user to re-authenticate to Yahoo. prompt: 'login', // Localize to French. language: 'fr' });
برای پارامترهایی که یاهو پشتیبانی می کند، به مستندات Yahoo OAuth مراجعه کنید. توجه داشته باشید که نمیتوانید پارامترهای مورد نیاز Firebase را با
setCustomParameters()
ارسال کنید. این پارامترها عبارتند از client_id , redirect_uri , answer_type , scope و state .اختیاری : دامنه های OAuth 2.0 اضافی را فراتر از
profile
وemail
که می خواهید از ارائه دهنده احراز هویت درخواست کنید، مشخص کنید. اگر برنامه شما نیاز به دسترسی به دادههای کاربر خصوصی از APIهای یاهو دارد، باید مجوزهای APIهای یاهو را تحت مجوزهای API در کنسول توسعهدهنده یاهو درخواست کنید. دامنه های درخواستی OAuth باید دقیقاً مطابق با موارد از پیش پیکربندی شده در مجوزهای API برنامه باشد. به عنوان مثال، اگر دسترسی خواندن/نوشتن به مخاطبین کاربر درخواست شود و در مجوزهای API برنامه از قبل پیکربندی شده باشد، بایدsdct-w
به جای دامنه OAuth فقط خواندنیsdct-r
ارسال شود. در غیر این صورت، جریان با شکست مواجه می شود و یک خطا به کاربر نهایی نشان داده می شود.// Request access to Yahoo Mail API. provider.addScope('mail-r'); // Request read/write access to user contacts. // This must be preconfigured in the app's API permissions. provider.addScope('sdct-w');
// Request access to Yahoo Mail API. provider.addScope('mail-r'); // Request read/write access to user contacts. // This must be preconfigured in the app's API permissions. provider.addScope('sdct-w');
برای کسب اطلاعات بیشتر، به مستندات حوزه یاهو مراجعه کنید.
با استفاده از شی ارائه دهنده OAuth با Firebase احراز هویت کنید. می توانید با باز کردن یک پنجره بازشو یا با هدایت مجدد به صفحه ورود به سیستم از کاربران خود بخواهید با حساب های یاهو خود وارد شوند. روش تغییر مسیر در دستگاه های تلفن همراه ترجیح داده می شود.
برای ورود به سیستم با یک پنجره بازشو،
signInWithPopup
را تماس بگیرید:import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth"; const auth = getAuth(); signInWithPopup(auth, provider) .then((result) => { // IdP data available in result.additionalUserInfo.profile // ... // Yahoo OAuth access token and ID token can be retrieved by calling: const credential = OAuthProvider.credentialFromResult(result); const accessToken = credential.accessToken; const idToken = credential.idToken; }) .catch((error) => { // Handle error. });
firebase.auth().signInWithPopup(provider) .then((result) => { // IdP data available in result.additionalUserInfo.profile // ... /** @type {firebase.auth.OAuthCredential} */ const credential = result.credential; // Yahoo OAuth access token and ID token can be retrieved by calling: var accessToken = credential.accessToken; var idToken = credential.idToken; }) .catch((error) => { // Handle error. });
برای ورود به سیستم با تغییر مسیر به صفحه ورود به سیستم،
signInWithRedirect
تماس بگیرید:
هنگام استفاده از
signInWithRedirect
،linkWithRedirect
، یاreauthenticateWithRedirect
، بهترین شیوه ها را دنبال کنید.firebase.auth().signInWithRedirect(provider);
پس از تکمیل ورود کاربر و بازگشت به صفحه، می توانید با فراخوانی
getRedirectResult
نتیجه ورود را دریافت کنید.import { getAuth, signInWithRedirect } from "firebase/auth"; const auth = getAuth(); signInWithRedirect(auth, provider);
firebase.auth().signInWithRedirect(provider);
پس از تکمیل موفقیت آمیز، کد OAuth ID و نشانه دسترسی مرتبط با ارائه دهنده را می توان از شی
firebase.auth.UserCredential
بازیابی کرد.با استفاده از نشانه دسترسی OAuth، میتوانید با Yahoo API تماس بگیرید.
به عنوان مثال، برای دریافت اطلاعات اولیه پروفایل، REST API زیر را می توان فراخوانی کرد:
curl -i -H "Authorization: Bearer ACCESS_TOKEN" https://social.yahooapis.com/v1/user/YAHOO_USER_UID/profile?format=json
جایی که
YAHOO_USER_UID
شناسه کاربر یاهو است که می تواند از فیلدfirebase.auth().currentUser.providerData[0].uid
یا ازresult.additionalUserInfo.profile
بازیابی شود.در حالی که مثالهای بالا بر جریانهای ورود تمرکز دارند، شما همچنین میتوانید با استفاده از
linkWithPopup
/linkWithRedirect
یک ارائهدهنده یاهو را به یک کاربر موجود پیوند دهید. برای مثال، میتوانید چندین ارائهدهنده را به یک کاربر پیوند دهید و به آنها اجازه دهید با هر یک از آنها وارد سیستم شوند.import { getAuth, linkWithPopup, OAuthProvider } from "firebase/auth"; const provider = new OAuthProvider('yahoo.com'); const auth = getAuth(); linkWithPopup(auth.currentUser, provider) .then((result) => { // Yahoo credential is linked to the current user. // IdP data available in result.additionalUserInfo.profile. // Get the OAuth access token and ID Token const credential = OAuthProvider.credentialFromResult(result); const accessToken = credential.accessToken; const idToken = credential.idToken; }) .catch((error) => { // Handle error. });
var provider = new firebase.auth.OAuthProvider('yahoo.com'); firebase.auth().currentUser.linkWithPopup(provider) .then((result) => { // Yahoo credential is linked to the current user. // IdP data available in result.additionalUserInfo.profile. // Yahoo OAuth access token can be retrieved by calling: // result.credential.accessToken // Yahoo OAuth ID token can be retrieved by calling: // result.credential.idToken }) .catch((error) => { // Handle error. });
از همین الگو می توان با
reauthenticateWithPopup
/reauthenticateWithRedirect
استفاده کرد که می تواند برای بازیابی اعتبارنامه های جدید برای عملیات حساسی که نیاز به ورود اخیر دارند استفاده شود.import { getAuth, reauthenticateWithPopup, OAuthProvider } from "firebase/auth"; const provider = new OAuthProvider('yahoo.com'); const auth = getAuth(); reauthenticateWithPopup(auth.currentUser, provider) .then((result) => { // User is re-authenticated with fresh tokens minted and // should be able to perform sensitive operations like account // deletion and email or password update. // IdP data available in result.additionalUserInfo.profile. // Get the OAuth access token and ID Token const credential = OAuthProvider.credentialFromResult(result); const accessToken = credential.accessToken; const idToken = credential.idToken; }) .catch((error) => { // Handle error. });
var provider = new firebase.auth.OAuthProvider('yahoo.com'); firebase.auth().currentUser.reauthenticateWithPopup(provider) .then((result) => { // User is re-authenticated with fresh tokens minted and // should be able to perform sensitive operations like account // deletion and email or password update. // IdP data available in result.additionalUserInfo.profile. // Yahoo OAuth access token can be retrieved by calling: // result.credential.accessToken // Yahoo OAuth ID token can be retrieved by calling: // result.credential.idToken }) .catch((error) => { // Handle error. });
Handling account-exists-with-different-credential Errors
اگر تنظیمات یک حساب برای هر آدرس ایمیل را در کنسول Firebase فعال کرده باشید، زمانی که کاربر سعی میکند با ایمیلی که از قبل برای ارائهدهنده کاربر دیگر Firebase (مانند Google) وجود دارد، به یک ارائهدهنده (مانند Yahoo) وارد شود، این خطا وجود دارد. auth/account-exists-with-different-credential
همراه با یک شی AuthCredential
(اعتبار یاهو) پرتاب می شود. برای تکمیل ورود به سیستم ارائهدهنده مورد نظر، کاربر باید ابتدا به ارائهدهنده موجود (Google) وارد شود و سپس به AuthCredential
قبلی (اعتبار یاهو) پیوند دهد.
حالت پاپ آپ
اگر از signInWithPopup
استفاده می کنید، می توانید خطاهای auth/account-exists-with-different-credential
با کدهایی مانند مثال زیر مدیریت کنید:
import { getAuth, linkWithCredential, signInWithPopup, OAuthProvider, } from "firebase/auth"; try { // Step 1: User tries to sign in using Yahoo. let result = await signInWithPopup(getAuth(), new OAuthProvider()); } catch (error) { // Step 2: User's email already exists. if (error.code === "auth/account-exists-with-different-credential") { // The pending Yahoo credential. let pendingCred = error.credential; // Step 3: Save the pending credential in temporary storage, // Step 4: Let the user know that they already have an account // but with a different provider, and let them choose another // sign-in method. } } // ... try { // Step 5: Sign the user in using their chosen method. let result = await signInWithPopup(getAuth(), userSelectedProvider); // Step 6: Link to the Yahoo credential. // TODO: implement `retrievePendingCred` for your app. let pendingCred = retrievePendingCred(); if (pendingCred !== null) { // As you have access to the pending credential, you can directly call the // link method. let user = await linkWithCredential(result.user, pendingCred); } // Step 7: Continue to app. } catch (error) { // ... }
حالت تغییر مسیر
این خطا در حالت تغییر مسیر به روشی مشابه مدیریت می شود، با این تفاوت که اعتبار معلق باید بین تغییر مسیرهای صفحه (مثلاً با استفاده از ذخیره سازی جلسه) در حافظه پنهان ذخیره شود.
پیشرفته: جریان ورود به سیستم را به صورت دستی مدیریت کنید
برخلاف سایر ارائهدهندگان OAuth که توسط Firebase پشتیبانی میشوند، مانند Google، Facebook و Twitter، که ورود به سیستم را میتوان مستقیماً با اعتبارنامههای مبتنی بر توکن دسترسی OAuth انجام داد، Firebase Auth به دلیل ناتوانی سرور Firebase Auth برای تأیید مخاطبان توکن های دسترسی یاهو OAuth. این یک نیاز امنیتی حیاتی است و میتواند برنامهها و وبسایتها را در معرض حملات مجدد قرار دهد که در آن نشانه دسترسی یاهو OAuth بهدستآمده برای یک پروژه (مهاجم) میتواند برای ورود به پروژه دیگر (قربانی) استفاده شود. در عوض، Firebase Auth توانایی مدیریت کل جریان OAuth و تبادل کد مجوز را با استفاده از شناسه مشتری OAuth و راز پیکربندی شده در Firebase Console ارائه میدهد. از آنجایی که کد مجوز فقط می تواند همراه با یک شناسه/مخفی مشتری خاص استفاده شود، کد مجوزی که برای یک پروژه به دست آمده است را نمی توان با پروژه دیگر استفاده کرد.
اگر لازم است از این ارائه دهندگان در محیط های پشتیبانی نشده استفاده شود، باید از کتابخانه OAuth شخص ثالث و احراز هویت سفارشی Firebase استفاده شود. اولی برای احراز هویت با ارائهدهنده و دومی برای مبادله اعتبار ارائهدهنده با یک توکن سفارشی مورد نیاز است.
احراز هویت با Firebase در یک برنامه افزودنی Chrome
اگر در حال ساخت یک برنامه افزودنی Chrome هستید، راهنمای اسناد خارج از صفحه را ببینید.
سفارشی کردن دامنه تغییر مسیر برای ورود به یاهو
هنگام ایجاد پروژه، Firebase یک زیر دامنه منحصر به فرد برای پروژه شما فراهم می کند: https://my-app-12345.firebaseapp.com
.
این همچنین به عنوان مکانیزم تغییر مسیر برای ورود به سیستم OAuth استفاده می شود. این دامنه باید برای همه ارائه دهندگان OAuth پشتیبانی شده مجاز باشد. با این حال، این بدان معنی است که کاربران ممکن است در حین ورود به یاهو قبل از هدایت مجدد به برنامه، آن دامنه را ببینند: به: https://my-app-12345.firebaseapp.com ادامه دهید .
برای جلوگیری از نمایش ساب دامنه خود، می توانید یک دامنه سفارشی با Firebase Hosting راه اندازی کنید:
- مراحل 1 تا 3 را در تنظیم دامنه خود برای Hosting دنبال کنید. هنگامی که مالکیت دامنه خود را تأیید می کنید، Hosting یک گواهی SSL برای دامنه سفارشی شما ارائه می دهد.
- دامنه سفارشی خود را به لیست دامنه های مجاز در کنسول Firebase اضافه کنید:
auth.custom.domain.com
. - در صفحه راهاندازی کنسول یاهو یا OAuth، URL صفحه تغییر مسیر را که در دامنه سفارشی شما قابل دسترسی است، در لیست سفید قرار دهید:
https://auth.custom.domain.com/__/auth/handler
. - هنگامی که کتابخانه جاوا اسکریپت را مقداردهی اولیه می کنید، دامنه سفارشی خود را با فیلد
authDomain
مشخص کنید:var config = { apiKey: '...', // Changed from '
PROJECT_ID .firebaseapp.com'. authDomain: 'auth.custom.domain.com', databaseURL: 'https://PROJECT_ID .firebaseio.com', projectId: 'PROJECT_ID ', storageBucket: ' ', messagingSenderId: 'PROJECT_ID .firebasestorage.appSENDER_ID ' }; firebase.initializeApp(config);
مراحل بعدی
پس از اینکه کاربر برای اولین بار وارد سیستم شد، یک حساب کاربری جدید ایجاد میشود و به اعتبارنامهها (یعنی نام کاربری و رمز عبور، شماره تلفن یا اطلاعات ارائهدهنده تاییدیه) مرتبط میشود که کاربر با آن وارد شده است. این حساب جدید بهعنوان بخشی از پروژه Firebase شما ذخیره میشود و میتوان از آن برای شناسایی کاربر در همه برنامههای پروژه شما، صرف نظر از نحوه ورود کاربر به سیستم استفاده کرد.
در برنامه های شما، روش توصیه شده برای اطلاع از وضعیت احراز هویت کاربر، تنظیم یک ناظر بر روی شی
Auth
است. سپس می توانید اطلاعات اولیه پروفایل کاربر را از شیUser
دریافت کنید. به مدیریت کاربران مراجعه کنید.در قوانین امنیتی Firebase Realtime Database و Cloud Storage خود، میتوانید شناسه کاربری منحصر به فرد کاربر واردشده به سیستم را از متغیر
auth
دریافت کنید و از آن برای کنترل دادههایی که کاربر میتواند به آن دسترسی داشته باشد استفاده کنید.
میتوانید به کاربران اجازه دهید با استفاده از چندین ارائهدهنده احراز هویت، با پیوند دادن اعتبار ارائهدهنده تأیید اعتبار به یک حساب کاربری موجود، به برنامه شما وارد شوند.
برای خروج از سیستم کاربر، با signOut
تماس بگیرید:
import { getAuth, signOut } from "firebase/auth"; const auth = getAuth(); signOut(auth).then(() => { // Sign-out successful. }).catch((error) => { // An error happened. });
firebase.auth().signOut().then(() => { // Sign-out successful. }).catch((error) => { // An error happened. });