Библиотека OAuth клиента для Swift (iOS/macOS)
OAuth (Open Authorization) — это открытый протокол авторизации, который позволяет приложениям получать ограниченный доступ к ресурсам пользователя без передачи его логина и пароля. В экосистеме Apple (iOS, macOS, watchOS, tvOS) реализация OAuth 2.0 является стандартом для интеграции с такими сервисами, как Google, Facebook, GitHub, Twitter и многими другими. Для Swift-разработчиков существует несколько проверенных библиотек, упрощающих процесс аутентификации и управления токенами.
В этой статье мы рассмотрим одну из наиболее популярных и гибких библиотек — OAuthSwift, а также обсудим альтернативу — AppAuth-iOS (рекомендуемую Google). Вы узнаете, как подключить библиотеку, выполнить авторизацию, получить access token, refresh token и безопасно их хранить.
Основные возможности OAuthSwift
- Поддержка OAuth 1.0 и OAuth 2.0
- Встроенная работа с WebView (SFSafariViewController, WKWebView)
- Автоматическое получение и обновление access token
- Поддержка различных грантов (Authorization Code, Implicit, Client Credentials, Resource Owner Password)
- Простая интеграция с Alamofire, URLSession и другими сетевыми фреймворками
- Асинхронные колбэки (completion handlers) и поддержка Combine (через расширения)
- Безопасное хранение токенов через Keychain
Установка OAuthSwift
Библиотека устанавливается через Swift Package Manager (SPM) или CocoaPods. Пример для SPM:
// В Xcode: File → Add Packages...
// URL: https://github.com/OAuthSwift/OAuthSwift.git
// Версия: от 2.2.0 и выше
Или через Package.swift:
dependencies: [
.package(url: "https://github.com/OAuthSwift/OAuthSwift.git", from: "2.2.0")
]
Пример интеграции с OAuth 2.0 (Google)
Рассмотрим типовой сценарий — авторизация через Google с получением access token. Предварительно необходимо зарегистрировать приложение в Google Cloud Console и получить client_id и client_secret.
Шаг 1. Настройка URL scheme
В файле Info.plist добавьте схему для обратного вызова:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>com.googleusercontent.apps.YOUR_CLIENT_ID</string>
</array>
</dict>
</array>
Шаг 2. Код авторизации
import OAuthSwift
let oauthswift = OAuth2Swift(
consumerKey: "YOUR_CLIENT_ID",
consumerSecret: "YOUR_CLIENT_SECRET",
authorizeUrl: "https://accounts.google.com/o/oauth2/auth",
accessTokenUrl: "https://oauth2.googleapis.com/token",
responseType: "code"
)
// Сохраняем ссылку на контроллер для презентации WebView
let handler = SafariURLHandler(viewController: self, oauthSwift: oauthswift)
oauthswift.authorizeURLHandler = handler
let state = generateState(withLength: 20)
oauthswift.authorize(
withCallbackURL: URL(string: "com.googleusercontent.apps.YOUR_CLIENT_ID:/oauth2callback")!,
scope: "https://www.googleapis.com/auth/userinfo.email",
state: state,
parameters: [:]) { result in
switch result {
case .success(let (credential, response, parameters)):
print("Access Token: \(credential.oauthToken)")
print("Refresh Token: \(credential.oauthRefreshToken)")
// Сохраняем токены в Keychain
KeychainWrapper.standard.set(credential.oauthToken, forKey: "access_token")
KeychainWrapper.standard.set(credential.oauthRefreshToken, forKey: "refresh_token")
case .failure(let error):
print("Ошибка авторизации: \(error.localizedDescription)")
}
}
Шаг 3. Обновление токена (refresh)
Когда access token истекает, используйте refresh token для получения нового:
oauthswift.renewAccessToken(
withRefreshToken: "YOUR_REFRESH_TOKEN",
parameters: [:]) { result in
switch result {
case .success(let (credential, response, parameters)):
print("Новый access token: \(credential.oauthToken)")
// Обновляем в Keychain
KeychainWrapper.standard.set(credential.oauthToken, forKey: "access_token")
case .failure(let error):
print("Не удалось обновить токен: \(error)")
}
}
Безопасное хранение токенов
Никогда не храните токены в