تساعدك مكتبة JavaScript google.accounts.oauth2 في طلب موافقة المستخدم والحصول على رمز دخول للعمل مع بيانات المستخدم. تستند هذه المكتبة إلى مسار
OAuth 2.0 المنحة الضمنية، وهي مصمّمة للسماح لك إما باستدعاء Google
APIs مباشرةً باستخدام REST وCORS، أو استخدام مكتبة عميل Google APIs لـ
JavaScript (المعروفة أيضًا باسم gapi.client) للوصول بمرونة إلى واجهات برمجة التطبيقات الأكثر تعقيدًا.
قبل الوصول إلى بيانات المستخدم المحمية من متصفّح، يبدأ المستخدمون على موقعك الإلكتروني عمليات محدد الحساب وتسجيل الدخول والموافقة المستندة إلى الويب من Google، وأخيرًا، تصدر خوادم OAuth من Google رمز دخول إلى تطبيق الويب الخاص بك وتعرضه.
في نموذج التفويض المستند إلى الرمز المميّز، ما مِن حاجة إلى تخزين رموز إعادة التحميل لكل مستخدم على خادمك الخلفي.
ننصحك باتّباع النهج الموضّح هنا بدلاً من الـ أساليب التي يغطيها دليل OAuth 2.0 القديم لتطبيقات الويب من جهة العميل.
المتطلبات الأساسية
اتّبِع الخطوات الموضّحة في الإعداد لضبط شاشة طلب الموافقة في OAuth ، والحصول على معرّف عميل، وتحميل مكتبة العميل.
تهيئة عميل رمز مميّز
استدعِ الد0/} لتهيئة عميل رمز مميّز جديد باستخدام معرّف عميل تطبيق الويب الخاص بك، وعليك تضمين قائمة بنطاق واحد أو أكثر يحتاج المستخدم إلى الوصول إليه:initTokenClient()
const client = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
callback: (response) => {
...
},
});
بدء مسار رمز OAuth 2.0 المميز
استخدِم الطريقة requestAccessToken() لبدء مسار تجربة المستخدم للرمز المميز والحصول على رمز دخول. تطلب Google من المستخدم ما يلي:
- اختيار حسابه،
- تسجيل الدخول إلى "حساب Google" إذا لم يسبق له ذلك،
- منح الموافقة لتطبيق الويب الخاص بك للوصول إلى كل نطاق مطلوب.
يؤدي إجراء تفاعلي من المستخدم إلى بدء مسار الرمز المميز:
<button onclick="client.requestAccessToken();">Authorize me</button>
بعد ذلك، تعرض Google عنصر TokenResponse يحتوي على رمز دخول وقائمة بالنطاقات التي منح المستخدم إذن الوصول إليها، أو خطأ، إلى معالج رد الاتصال.
قد يغلق المستخدمون نافذتَي اختيار الحساب أو تسجيل الدخول، وفي هذه الحالة لن يتم استدعاء دالّة رد الاتصال.
كيفية التعامل مع الموافقة
يجب تنفيذ تصميم تطبيقك وتجربة المستخدم فيه بعد مراجعة دقيقة لسياسات OAuth 2.0 من Google فقط. تغطي هذه السياسات العمل مع نطاقات متعددة، وتحديد وقت وكيفية التعامل مع موافقة المستخدم، والمزيد.
التفويض التدريجي هو سياسة ومنهجية لتصميم التطبيقات تُستخدم لطلب الوصول إلى الموارد، باستخدام النطاقات، عند الحاجة فقط بدلاً من طلبها مسبقًا ومرة واحدة. يمكن للمستخدمين الموافقة على مشاركة الموارد الفردية التي يطلبها تطبيقك أو رفضها، ويُعرف ذلك باسم الأذونات الدقيقة.
أثناء هذه العملية، تطلب Google موافقة المستخدم، وتدرج كل نطاق مطلوب على حدة، ويختار المستخدمون الموارد التي ستتم مشاركتها مع تطبيقك، وأخيرًا، تستدعي Google دالّة رد الاتصال لعرض رمز دخول والنطاقات التي وافق عليها المستخدم. بعد ذلك، يتعامل تطبيقك بأمان مع النتائج المختلفة المحتملة باستخدام الأذونات الدقيقة.
ومع ذلك، هناك استثناءات. تتجاوز تطبيقات Google Workspace Enterprise التي تتضمّن تفويضًا على مستوى النطاق أو التطبيقات المصنّفة على أنّها موثوق بها، شاشة طلب الموافقة على الأذونات الدقيقة. بالنسبة إلى هذه التطبيقات، لن تظهر للمستخدمين شاشة طلب الموافقة على الأذونات الدقيقة. بدلاً من ذلك، سيتلقّى تطبيقك إما جميع النطاقات المطلوبة أو لا شيء منها.
لمزيد من المعلومات التفصيلية، يُرجى الاطّلاع على كيفية التعامل مع الأذونات الدقيقة.
التفويض التدريجي
بالنسبة إلى تطبيقات الويب، يوضّح السيناريوهان التاليان على المستوى العالي التفويض التدريجي باستخدام:
- تطبيق Ajax من صفحة واحدة، غالبًا ما يستخدم
XMLHttpRequestمع إمكانية الوصول الديناميكي إلى الموارد. - صفحات ويب متعددة، يتم فصل الموارد وإدارتها على أساس كل صفحة.
يتم عرض هذين السيناريوهَين لتوضيح اعتبارات التصميم والمنهجيات، ولكن ليس المقصود منهما تقديم توصيات شاملة حول كيفية تضمين الموافقة في تطبيقك. قد تستخدم التطبيقات الحقيقية مجموعة متنوعة أو مزيجًا من هذه الأساليب.
Ajax
يمكنك إضافة إمكانية استخدام التفويض التدريجي إلى تطبيقك من خلال إجراء عدة طلبات إلى requestAccessToken() واستخدام المَعلمة scope في عنصر OverridableTokenClientConfig لطلب نطاقات فردية في الوقت الذي تكون فيه مطلوبة وعند الضرورة فقط. في هذا المثال، لن يتم طلب الموارد وعرضها إلا بعد أن يوسّع المستخدم قسم محتوى مضغوطًا.
| تطبيق Ajax |
|---|
يمكنك تهيئة عميل الرمز المميز عند تحميل الصفحة:
const client = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
callback: "onTokenResponse",
});
المستندات التي يجب قراءتهاعرض المستندات الأخيرة
client.requestAccessToken(
overrideConfig = ({
scope = 'https://www.googleapis.com/auth/documents.readonly'
})
);
الأحداث القادمةعرض معلومات التقويم
client.requestAccessToken(
overrideConfig = ({
scope = 'https://www.googleapis.com/auth/calendar.readonly'
})
);
منصّة عرض الصور المتغيّرةعرض الصور
client.requestAccessToken(
overrideConfig = ({
scope = 'https://www.googleapis.com/auth/photoslibrary.readonly'
})
);
|
يؤدي كل طلب إلى requestAccessToken إلى بدء لحظة موافقة المستخدم، ولن يتمكّن تطبيقك من الوصول إلا إلى الموارد المطلوبة في القسم الذي يختار المستخدم توسيعه، ما يحدّ من مشاركة الموارد من خلال اختيار المستخدم.
صفحات ويب متعددة
عند تصميم التفويض التدريجي، يتم استخدام صفحات متعددة لطلب النطاقات المطلوبة فقط لتحميل صفحة، ما يقلّل من التعقيد والحاجة إلى إجراء طلبات متعددة للحصول على موافقة المستخدم واسترداد رمز دخول.
| تطبيق من عدة صفحات | ||||||||
|---|---|---|---|---|---|---|---|---|
|
تطلب كل صفحة النطاق اللازم وتحصل على رمز دخول من خلال استدعاء initTokenClient() وrequestAccessToken() في مدّة التحميل. في هذا السيناريو، يتم استخدام صفحات ويب فردية لفصل وظائف المستخدم والموارد بوضوح حسب النطاق. في حالة حقيقية، قد تطلب الصفحات الفردية نطاقات متعددة ذات صلة.
الأذونات الدقيقة
يتم التعامل مع الأذونات الدقيقة بالطريقة نفسها في جميع السيناريوهات؛ بعد أن يستدعي requestAccessToken() دالّة رد الاتصال ويعرض رمز دخول، تحقَّق من أنّ المستخدم قد وافق على النطاقات المطلوبة باستخدام hasGrantedAllScopes() أو hasGrantedAnyScope(). على سبيل المثال:
const client = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly \
https://www.googleapis.com/auth/documents.readonly \
https://www.googleapis.com/auth/photoslibrary.readonly',
callback: (tokenResponse) => {
if (tokenResponse && tokenResponse.access_token) {
if (google.accounts.oauth2.hasGrantedAnyScope(tokenResponse,
'https://www.googleapis.com/auth/photoslibrary.readonly')) {
// Look at pictures
...
}
if (google.accounts.oauth2.hasGrantedAllScopes(tokenResponse,
'https://www.googleapis.com/auth/calendar.readonly',
'https://www.googleapis.com/auth/documents.readonly')) {
// Meeting planning and review documents
...
}
}
},
});
سيتم أيضًا تضمين أي منح تم قبولها سابقًا من الجلسات أو الطلبات السابقة في الرد. يتم الاحتفاظ بسجلّ لموافقة المستخدم لكل مستخدم ومعرّف عميل، ويظل هذا السجلّ ساريًا على مستوى عدة طلبات إلى initTokenClient() أو requestAccessToken(). تلقائيًا، لا تكون موافقة المستخدم ضرورية إلا في المرة الأولى التي يزور فيها المستخدم موقعك الإلكتروني ويطلب نطاقًا جديدًا، ولكن قد يُطلب ذلك في كل مرة يتم فيها تحميل الصفحة باستخدام prompt=consent في عناصر إعداد عميل الرمز المميز.
العمل مع الرموز المميّزة
في نموذج الرمز المميز، لا يتم تخزين رمز الدخول بواسطة نظام التشغيل أو المتصفّح، بل يتم الحصول أولاً على رمز مميّز جديد في وقت تحميل الصفحة، أو لاحقًا من خلال بدء استدعاء requestAccessToken() من خلال إجراء تفاعلي من المستخدم، مثل الضغط على زر.
استخدام REST وCORS مع Google APIs
يمكن استخدام رمز الدخول لإجراء طلبات مصادقة إلى Google APIs باستخدام REST وCORS. يتيح ذلك للمستخدمين تسجيل الدخول ومنح الموافقة، ولـ Google إصدار رمز دخول، ولموقعك الإلكتروني العمل مع بيانات المستخدم.
في هذا المثال، يمكنك الاطّلاع على أحداث التقويم القادمة للمستخدمين الذين سجّلوا الدخول باستخدام رمز الدخول الذي يعرضه tokenRequest():
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/calendar/v3/calendars/primary/events');
xhr.setRequestHeader('Authorization', 'Bearer ' + tokenResponse.access_token);
xhr.send();
تتيح Google APIs استخدام CORS تلقائيًا، بما في ذلك رمز الدخول في طلب XMLHttpRequest أو fetch الذي يبدأ عملية فحص CORS قبل إرسال الطلب؛ وهو طلب OPTIONS قبل طلب GET أو POST.
يوضّح القسم التالي كيفية التكامل مع واجهات برمجة التطبيقات الأكثر تعقيدًا.
العمل مع مكتبة JavaScript لـ Google APIs
يعمل عميل الرمز المميز مع مكتبة عميل Google API لـ JavaScript اطّلِع على مقتطف الرمز البرمجي التالي.
const client = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
callback: (tokenResponse) => {
if (tokenResponse && tokenResponse.access_token) {
gapi.client.setApiKey('YOUR_API_KEY');
gapi.client.load('calendar', 'v3', listUpcomingEvents);
}
},
});
function listUpcomingEvents() {
gapi.client.calendar.events.list(...);
}
انتهاء صلاحية الرمز المميز
بطبيعة الحال، تكون مدة صلاحية رموز الدخول قصيرة. إذا انتهت صلاحية رمز الدخول قبل انتهاء جلسة المستخدم، احصل على رمز مميّز جديد من خلال استدعاء requestAccessToken() من حدث من المستخدم، مثل الضغط على زر.
استخدام رمز دخول لإبطال الموافقة
استدعِ الطريقة google.accounts.oauth2.revoke لإزالة موافقة المستخدم وإمكانية الوصول إلى الموارد لجميع النطاقات التي تم منحها لتطبيقك. يجب توفّر رمز دخول صالح لإبطال هذا الإذن:
google.accounts.oauth2.revoke('414a76cb127a7ece7ee4bf287602ca2b56f8fcbf7fcecc2cd4e0509268120bd7', done => {
console.log(done);
console.log(done.successful);
console.log(done.error);
console.log(done.error_description);
});