كيفية استخدام Google Oauth 2.0 للوصول إلى Google APIs مع رمز التحديث

دعنا نبني تطبيق ويب بسيط يستخدم Google Oauth 2.0 للوصول إلى Google APIs. يمكن للمستخدم تسجيل الدخول مع حساب Google الخاص بهم وتفويض التطبيق للوصول إلى Google Drive أو أي خدمة Google أخرى.
عندما يقوم المستخدم بتسجيل الدخول ، تقوم Google بإعادة توجيه المستخدم إلى صفحة إذن Google OAUTH 2.0. يطلب من المستخدم منح الوصول إلى التطبيق. يقوم التطبيق بعد ذلك بتبادل رمز التفويض لرمز الوصول ورمز تحديث. سوف ينتهي رمز الوصول بعد ساعة ولكن رمز التحديث سيكون صالحًا إلى أجل غير مسمى (ما لم يتم إلغاء المستخدم يدويًا).
سنقوم بالتالي بتخزين رمز التحديث في Cloud Firestore ، ونستخدمه لإنشاء رمز وصول جديد كلما احتاج التطبيق للوصول إلى واجهات برمجة تطبيقات Google نيابة عن المستخدم.
نحن لا نستخدم تسجيل الدخول إلى Google مع مصادقة Firebase لأنه لا يوفر رمزًا للتحديث المطلوب لتشغيل مهام API للخلفية دون مراقبة.
الخطوة 1: إنشاء عميل Google Oauth 2.0
قم بإنشاء عميل جديد OAUTH 2.0 داخل مشروع Google Cloud الخاص بك كما هو موضح في دليل الخطوة بخطوة.
داخل وحدة التحكم السحابة في Google ، انتقل إلى APIs & Services
القسم ، انقر فوق Credentials
وانقر فوق Create credentials
> OAuth Client Id
لإنشاء معرف عميل جديد.
أثناء التنمية ، يمكنك وضع https://localhost:5001/oauthCallback
نظرًا لأن URI Redirect منذ محاكي Firebase ، بشكل افتراضي ، سيقوم بتشغيل تطبيق الويب محليًا على المنفذ 5001.
قم بتدوين معرف العميل وسرية العميل المقدمة من Google.
الخطوة 2: تهيئة وظيفة Firebase
افتح المحطة الخاصة بك ، وإنشاء دليل مشروع جديد وتهيئة مشروع Firebase.
$ mkdir oauth2-application
$ cd oauth2-application
$ npx firebase init functions
$ npm install googleapis
يمكنك اختيار Use an existing Firebase project
الخيار ثم حدد مشروع Google Cloud الخاص بك مع الوظيفة. التبديل إلى functions
دليل.
الخطوة 3. تهيئة متغيرات بيئة Firebase
إنشاء جديد .env
الملف وإضافة متغيرات البيئة التالية:
CLIENT_ID=<your client ID>
CLIENT_SECRET=<your client secret>
REDIRECT_URI=<your redirect URI>
الخطوة 4. إنشاء عنوان URL للترخيص
سنقوم بإنشاء وظيفة تقوم بإنشاء عنوان URL للترخيص للمستخدم للتسجيل في حساب Google الخاص به. بالإضافة إلى drive
النطاق ، طلبنا يطلب أيضًا userinfo.email
النطاق للحصول على عنوان البريد الإلكتروني للمستخدم.
const functions = require('firebase-functions');
const { google } = require('googleapis');
exports.googleLogin = functions.https.onRequest((request, response) => {
const SCOPES = [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/drive.metadata.readonly'
];
const oAuth2Client = new google.auth.OAuth2(
process.env.CLIENT_ID,
process.env.CLIENT_SECRET,
process.env.REDIRECT_URI
);
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
prompt: 'consent',
login_hint: request.query.email_address || ''
});
response.set('Cache-Control', 'private, max-age=0, s-maxage=0');
response.redirect(authUrl);
});
وضعنا access_type
ل offline
للحصول على رمز تحديث. ال consent
تم تعيينه على prompt
لإجبار المستخدم على الموافقة على التطبيق. نحن أيضا وضعنا login_hint
إلى عنوان البريد الإلكتروني للمستخدم إذا تم تسجيله إلى حسابات Google متعددة.
الخطوة 5. تخزين رمز التحديث
بمجرد تسجيل الدخول ، تقوم Google بإعادة توجيه المستخدم إلى URI إعادة توجيه. يحتوي URI المعاد توجيهًا على رمز التفويض الذي نحتاجه إلى تبادل رمز الوصول إلى الرمز المميز وتحديث الرمز المميز للتخزين في قاعدة البيانات.
const functions = require('firebase-functions');
const { firestore as adminFirestore } = require('firebase-admin');
const { google } = require('googleapis');
admin.initializeApp();
exports.oAuthCallback = functions.https.onRequest(async (request, response) => {
const { query: { error, code } = {} } = request;
// User may deny access to the application.
if (error) {
response.status(500).send(error);
return;
}
const oAuth2Client = new google.auth.OAuth2(
process.env.CLIENT_ID,
process.env.CLIENT_SECRET,
process.env.REDIRECT_URI
);
// Exchange the authorization code for an access token.
const { tokens } = await oAuth2Client.getToken(code);
oAuth2Client.setCredentials(tokens);
const oauth2 = google.oauth2({
auth: oAuth2Client,
version: 'v2',
});
// Get the user's email address and Google user ID
const { data } = await oauth2.userinfo.get();
const { id, email } = data;
const { refresh_token } = tokens;
// Store the refresh token in the Firestore database.
// Set merge: true to not overwrite any other data in the same document
const firestore = adminFirestore();
const usersCollection = firestore.collection('users');
await usersCollection.doc(id).set({ id, email, refresh_token }, { merge: true });
response.set('Cache-Control', 'private, max-age=0, s-maxage=0');
response.send(`User ${email} is authorized! ${id}`);
});
إليك كيفية تخزين المستندات في قاعدة بيانات Firestore NOSQL:
الخطوة 6: الوصول إلى Google APIs
الآن بعد أن أصبح لدينا رمز التحديث ، يمكننا استخدامه لإنشاء رمز الوصول الجديد والوصول إلى واجهات برمجة تطبيقات Google. في مثالنا ، ستعيد وظيفة محرك الأقراص أحدث 5 ملفات من Google Drive للمستخدم المعتمد.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const { google } = require('googleapis');
admin.initializeApp();
exports.drive = functions.https.onRequest(async (request, response) => {
const { user_id = '' } = request.query;
const user = await admin.firestore().collection('users').doc(user_id).get();
if (!user.exists) {
response.status(404).send(`User ${user_id} not found`);
return;
}
const { refresh_token } = user.data();
const oAuth2Client = new google.auth.OAuth2(
process.env.CLIENT_ID,
process.env.CLIENT_SECRET,
process.env.REDIRECT_URI
);
oAuth2Client.setCredentials({ refresh_token });
const googleDrive = google.drive({ version: 'v3', auth: oAuth2Client });
const { data: { files = [] } = {} } = await googleDrive.files.list({
pageSize: 5,
fields: 'files(id, name)'
});
response.status(200).send({ files });
});
الخطوة 7: إنشاء وظيفة سحابة Firebase
يمكنك تشغيل الأمر التالي لاختبار الوظائف محليًا:
firebase emulators:start --only functions
عندما تكون مستعدًا لنشر الوظائف في مشروع Firebase الخاص بك ، يمكنك تشغيل الأمر التالي:
firebase deploy --only functions
اكتشاف المزيد من مرابع التكنولوجيا
اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.