مكتبة عميل OAuth لتطبيقات Swift (iOS/macOS)
\n\nOAuth (الترخيص المفتوح) هو بروتوكول ترخيص مفتوح يسمح للتطبيقات بالحصول على وصول محدود إلى موارد المستخدم دون نقل اسم المستخدم وكلمة المرور الخاصة به. في نظام Apple البيئي (iOS، macOS، watchOS، tvOS)، يُعد تطبيق OAuth 2.0 معيارًا للتكامل مع خدمات مثل Google وFacebook وGitHub وTwitter وغيرها الكثير. بالنسبة لمطوري Swift، توجد عدة مكتبات موثوقة تُبسط عملية المصادقة وإدارة الرموز.
\n\nفي هذه المقالة، سنستعرض واحدة من أشهر المكتبات وأكثرها مرونة — OAuthSwift، بالإضافة إلى مناقشة بديل — AppAuth-iOS (الموصى به من Google). ستتعلم كيفية توصيل المكتبة، وتنفيذ عملية التفويض، والحصول على رمز الوصول (access token)، ورمز التحديث (refresh token)، وتخزينهما بشكل آمن.
\n\nالميزات الرئيسية لـ OAuthSwift
\n\n- \n
- دعم OAuth 1.0 و OAuth 2.0 \n
- العمل المدمج مع WebView (SFSafariViewController، WKWebView) \n
- الحصول التلقائي على رمز الوصول وتحديثه \n
- دعم أنواع المنح المختلفة (رمز التفويض، الضمني، بيانات العميل، كلمة مرور مالك المورد)
- تكامل بسيط مع Alamofire وURLSession وأطر الشبكات الأخرى
- استدعاءات غير متزامنة (completion handlers) ودعم Combine (من خلال الإضافات)
- تخزين آمن للرموز عبر Keychain
تثبيت OAuthSwift
\n\nيتم تثبيت المكتبة عبر Swift Package Manager (SPM) أو CocoaPods. مثال لـ SPM:
\n\n// في Xcode: File → Add Packages...\n// الرابط: https://github.com/OAuthSwift/OAuthSwift.git\n// الإصدار: من 2.2.0 فما فوق\n\nأو عبر Package.swift:
dependencies: [\n .package(url: "https://github.com/OAuthSwift/OAuthSwift.git", from: "2.2.0")\n]\n\nمثال على التكامل مع OAuth 2.0 (Google)
\n\nلنستعرض سيناريو نموذجي — التفويض عبر Google مع الحصول على رمز الوصول. يجب أولاً تسجيل التطبيق في Google Cloud Console والحصول على client_id و client_secret.
الخطوة 1. إعداد مخطط URL
\n\nفي ملف Info.plist، أضف مخططًا لاستدعاء الرجوع:
<key>CFBundleURLTypes</key>\n<array>\n <dict>\n <key>CFBundleURLSchemes</key>\n <array>\n <string>com.googleusercontent.apps.YOUR_CLIENT_ID</string>\n </array>\n </dict>\n</array>\n\nالخطوة 2. كود التفويض
\n\nimport OAuthSwift\n\nlet oauthswift = OAuth2Swift(\n consumerKey: "YOUR_CLIENT_ID",\n consumerSecret: "YOUR_CLIENT_SECRET",\n authorizeUrl: "https://accounts.google.com/o/oauth2/auth",\n accessTokenUrl: "https://oauth2.googleapis.com/token",\n responseType: "code"\n)\n\n// حفظ مرجع لوحدة التحكم لعرض WebView\nlet handler = SafariURLHandler(viewController: self, oauthSwift: oauthswift)\noauthswift.authorizeURLHandler = handler\n\nlet state = generateState(withLength: 20)\noauthswift.authorize(\n withCallbackURL: URL(string: "com.googleusercontent.apps.YOUR_CLIENT_ID:/oauth2callback")!,\n scope: "https://www.googleapis.com/auth/userinfo.email",\n state: state,\n parameters: [:]) { result in\n switch result {\n case .success(let (credential, response, parameters)):\n print("Access Token: \\(credential.oauthToken)")\n print("Refresh Token: \\(credential.oauthRefreshToken)")\n // حفظ الرموز في Keychain\n KeychainWrapper.standard.set(credential.oauthToken, forKey: "access_token")\n KeychainWrapper.standard.set(credential.oauthRefreshToken, forKey: "refresh_token")\n case .failure(let error):\n print("خطأ في التفويض: \\(error.localizedDescription)")\n