在WWDC 2019上,苹果再次打扰了iOS开发人员的安宁-引入了新的用户授权系统Sign in Apple。 现在,所有使用第三方授权系统的iOS应用程序(Facebook,Twitter等)都必须实现与Apple的登录,否则必须将其从AppStore中删除。 我们决定不吸引命运,而是跑去实现此功能。 我们如何做到这一点-在削减下找出来。
我们通过苹果写授权服务
在我们的工作中,我们使用VIPER + SOA架构,因此我们通过Apple作为单独的服务进行了授权。 首先,我们将数据包装在枚举中,以方便地扩展授权类型(Facebook,VK,Google等):
enum AuthToken { case apple(code: String, name: String) }
我们将使用
RxSwift的Observable传递结果:
protocol AuthProviderProtocol { var authResult: Observable<AuthToken> { get } func login() func logout() }
协议实施:
import AuthenticationServices import Foundation import RxSwift @available(iOS 13.0, *) class AppleAuthService: AuthProviderProtocol { private let authResultSubject = PublishSubject<AuthToken>() var authResult: Observable<AuthToken> { return authResultSubject.asObservable() } func login() { let appleIDProvider = ASAuthorizationAppleIDProvider() let request = appleIDProvider.createRequest() request.requestedScopes = [.fullName, .email] let authorizationController = ASAuthorizationController(authorizationRequests: [request]) authorizationController.delegate = self authorizationController.performRequests() } } @available(iOS 13.0, *) extension AppleAuthService: ASAuthorizationControllerDelegate { func authorizationController( controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization ) { guard let credential = authorization.credential as? ASAuthorizationAppleIDCredential, let tokenData = credential.authorizationCode, let token = String(data: tokenData, encoding: .utf8) else { return } let firstName = credential.fullName?.givenName let lastName = credential.fullName?.familyName authResultSubject.onNext(.apple(code: token, name: firstName + lastName)) } }
要知道的细微差别
- 从苹果这个词的经典意义上讲,登录没有注销功能。 与其他输入库不同,该库不存储任何数据,因此无需擦除通过登录接收的数据。
- 使用Apple登录在第一次登录时只收到一次用户的名字和姓氏。 服务器无权访问此数据。 在随后的登录尝试中,您将仅从ASAuthorizationAppleIDCredential收到authorizationCode 。 因此,在客户端,我们存储用户的名称和姓氏,直到在服务器上成功注册为止。
- 使用Apple登录可以使用户替换其电子邮件。 您只能从在developer.apple.com上的设置中指定的域中写入欺骗的电子邮件。
- 本文介绍了我们如何实现后端部分。
这篇文章虽然很小,但我们希望它对您有用。
感谢您的关注!