官方說(shuō)的比較詳細(xì),但是就是有些重復(fù),而且有很多坑
10年積累的成都網(wǎng)站建設(shè)、網(wǎng)站制作經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有信宜免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
在info.plist中加入安全域名白名單(右鍵info.plist用source code打開)
在info.plist的NSAppTransportSecurity下新增NSAllowsArbitraryLoads并設(shè)置為YES,指定所有HTTP連接都可正常請(qǐng)求
打開app,用第三方登錄,發(fā)現(xiàn)沒(méi)有sso授權(quán)頁(yè)面,或打開QQ失敗、微信失敗、微博失敗等
info.plist增加:
在iOS9下就需要增加一個(gè)可跳轉(zhuǎn)的白名單,指定對(duì)應(yīng)跳轉(zhuǎn)App的URL Scheme,否則將在第三方平臺(tái)判斷是否跳轉(zhuǎn)時(shí)用到的canOpenURL時(shí)返回NO,進(jìn)而只進(jìn)行webview授權(quán)或授權(quán)/分享失敗。
2020年4月后,有第三方平臺(tái)登錄的app必須有蘋果的第三方登錄
開發(fā)者賬號(hào)的app綁定的identifiers 中選中
在Xcode 中的
添加
在登錄界面添加?#import?AuthenticationServices/AuthenticationServices.h
if ( @available (iOS13.0, *)) {
? ? // Sign In With Apple Button
? ? ASAuthorizationAppleIDButton *appleIDBtn = [ASAuthorizationAppleIDButton buttonWithType:ASAuthorizationAppleIDButtonTypeDefault style:ASAuthorizationAppleIDButtonStyleWhite];
? ? appleIDBtn.frame=? CGRectMake(50,100,100,40);
? ? appleIDBtn.layer.cornerRadius=5;
? ? appleIDBtn.layer.masksToBounds= YES ;
? ? [appleIDBtnaddTarget: self action: @selector (handleAuthorizationAppleIDButtonPress)forControlEvents:UIControlEventTouchUpInside];
? ? [self.view addSubview:appleIDBtn];
}
//蘋果第三方登錄
-( void )handleAuthorizationAppleIDButtonPress{
if ( @available (iOS13.0, *)) {
? ? // 基于用戶的Apple ID授權(quán)用戶,生成用戶授權(quán)請(qǐng)求的一種機(jī)制
? ? ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];
? ? // 創(chuàng)建新的AppleID 授權(quán)請(qǐng)求
? ? ASAuthorizationAppleIDRequest*appleIDRequest = [appleIDProvidercreateRequest];
? ? // 在用戶授權(quán)期間請(qǐng)求的聯(lián)系信息
? ? appleIDRequest.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
? ? // 由ASAuthorizationAppleIDProvider創(chuàng)建的授權(quán)請(qǐng)求 管理授權(quán)請(qǐng)求的控制器
? ? ASAuthorizationController*authorizationController = [[ASAuthorizationControlleralloc]initWithAuthorizationRequests:@[appleIDRequest]];
? ? // 設(shè)置授權(quán)控制器通知授權(quán)請(qǐng)求的成功與失敗的代理
? ? authorizationController.delegate= self ;
? ? // 設(shè)置提供 展示上下文的代理,在這個(gè)上下文中 系統(tǒng)可以展示授權(quán)界面給用戶
? ? authorizationController.presentationContextProvider= self ;
? ? // 在控制器初始化期間啟動(dòng)授權(quán)流
? ? [authorizationControllerperformRequests];
}
}
// 如果存在iCloud Keychain 憑證或者AppleID 憑證提示用戶 ?
//這個(gè)方法在viewDidAppear里添加
- ( void )perfomExistingAccountSetupFlows{
NSLog(@"http:///已經(jīng)認(rèn)證過(guò)了/////");
if ( @available (iOS13.0, *)) {
? ? // 基于用戶的Apple ID授權(quán)用戶,生成用戶授權(quán)請(qǐng)求的一種機(jī)制
? ? ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];
? ? // 授權(quán)請(qǐng)求AppleID
? ? ASAuthorizationAppleIDRequest*appleIDRequest = [appleIDProvidercreateRequest];
? ? // 為了執(zhí)行鑰匙串憑證分享生成請(qǐng)求的一種機(jī)制
? ? ASAuthorizationPasswordProvider *passwordProvider = [[ASAuthorizationPasswordProvider alloc] init];
? ? ASAuthorizationPasswordRequest*passwordRequest = [passwordProvidercreateRequest];
? ? // 由ASAuthorizationAppleIDProvider創(chuàng)建的授權(quán)請(qǐng)求 管理授權(quán)請(qǐng)求的控制器
? ? ASAuthorizationController*authorizationController = [[ASAuthorizationControlleralloc]initWithAuthorizationRequests:@[appleIDRequest, passwordRequest]];
? ? // 設(shè)置授權(quán)控制器通知授權(quán)請(qǐng)求的成功與失敗的代理
? ? authorizationController.delegate= self ;
? ? // 設(shè)置提供 展示上下文的代理,在這個(gè)上下文中 系統(tǒng)可以展示授權(quán)界面給用戶
? ? authorizationController.presentationContextProvider= self ;
? ? // 在控制器初始化期間啟動(dòng)授權(quán)流
? ? [authorizationControllerperformRequests];
}
}
#pragma mark - delegate
//@optional 授權(quán)成功地回調(diào)
- ( void )authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization{
NSLog(@"授權(quán)完成:::%@", authorization.credential);
NSLog(@"%s", __FUNCTION__ );
NSLog(@"%@", controller);
NSLog(@"%@", authorization);
// 測(cè)試配置UI顯示
NSMutableString *mStr = [NSMutableString string];
if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
? ? // 用戶登錄使用ASAuthorizationAppleIDCredential
? ? ASAuthorizationAppleIDCredential*appleIDCredential = authorization.credential;
? ? NSString*user = appleIDCredential.user;
? ? NSString*familyName = appleIDCredential.fullName.familyName;
? ? NSString*givenName = appleIDCredential.fullName.givenName;
? ? NSString*email = appleIDCredential.email;
? NSString *authorizationCode = [[NSString alloc] initWithData:appleIDCredential.authorizationCode encoding:NSUTF8StringEncoding]; // refresh token
? ? NSString *identityToken = [[NSString alloc] initWithData:appleIDCredential.identityToken encoding:NSUTF8StringEncoding]; // access token
? ? ASUserDetectionStatusrealUserStatus = appleIDCredential.realUserStatus;
//? ? ? ? NSData *identityToken = appleIDCredential.identityToken;
//? ? ? ? NSData *authorizationCode = appleIDCredential.authorizationCode;
? ? // Create an account in your system.
? ? // For the purpose of this demo app, store the userIdentifier in the keychain.
? ? //? 需要使用鑰匙串的方式保存用戶的唯一信息
//? ? ? ? [mStr appendString:user];
//? ? ? ? [mStr appendString:@"\n"];
//? ? ? ? [mStr appendString:familyName];
//? ? ? ? [mStr appendString:@"\n"];
//? ? ? ? [mStr appendString:givenName];
//? ? ? ? [mStr appendString:@"\n"];
//? ? ? ? [mStr appendString:email];
//? ? ? ? NSLog(@"mStr:::%@", mStr);
//? ? ? ? [mStr appendString:@"\n"];
} else if ([authorization.credentialisKindOfClass:[ASPasswordCredentialclass]]){
? ? // Sign in using an existing iCloud Keychain credential.
? ? // 用戶登錄使用現(xiàn)有的密碼憑證
? ? ASPasswordCredential*passwordCredential = authorization.credential;
? ? // 密碼憑證對(duì)象的用戶標(biāo)識(shí) 用戶的唯一標(biāo)識(shí)
? ? NSString*user = passwordCredential.user;
? ? // 密碼憑證對(duì)象的密碼
? ? NSString*password = passwordCredential.password;
? ? [mStrappendString:user];
? ? [mStrappendString:@"\n"];
? ? [mStrappendString:password];
? ? [mStrappendString:@"\n"];
? ? NSLog(@"mStr:::%@", mStr);
} else {
? ? NSLog(@"授權(quán)信息均不符");
? ? mStr = [@"授權(quán)信息均不符"copy];
}
}
// 授權(quán)失敗的回調(diào)
- ( void )authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error{
// Handle error.
NSLog(@"Handle error:%@", error);
NSString*errorMsg = nil ;
switch (error.code) {
? ? case ASAuthorizationErrorCanceled:
? ? ? ? errorMsg =@"用戶取消了授權(quán)請(qǐng)求";
? ? ? ? break ;
? ? case ASAuthorizationErrorFailed:
? ? ? ? errorMsg =@"授權(quán)請(qǐng)求失敗";
? ? ? ? break ;
? ? case ASAuthorizationErrorInvalidResponse:
? ? ? ? errorMsg =@"授權(quán)請(qǐng)求響應(yīng)無(wú)效";
? ? ? ? break ;
? ? case ASAuthorizationErrorNotHandled:
? ? ? ? errorMsg =@"未能處理授權(quán)請(qǐng)求";
? ? ? ? break ;
? ? case ASAuthorizationErrorUnknown:
? ? ? ? errorMsg =@"授權(quán)請(qǐng)求失敗未知原因";
? ? ? ? break ;
? ? default :
? ? ? ? break ;
}
//? ? NSMutableString *mStr = [_appleIDInfoLabel.text mutableCopy];
//? ? [mStr appendString:@"\n"];
//? ? [mStr appendString:errorMsg];
//? ? [mStr appendString:@"\n"];
}
// 告訴代理應(yīng)該在哪個(gè)window 展示內(nèi)容給用戶
- (ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller{
NSLog(@"88888888888");
// 返回window
return self .view.window;
}
后臺(tái)進(jìn)行驗(yàn)證信息,返回驗(yàn)證信息過(guò)期,我一直在找原因,找了一天,后來(lái)發(fā)現(xiàn)是后臺(tái)code碼整錯(cuò)了,-1代表驗(yàn)證通過(guò),驗(yàn)證不通過(guò)是重新調(diào)用一下handleAuthorizationAppleIDButtonPress這個(gè)方法就可以,我甚至去看官方文檔,也沒(méi)有說(shuō)重新獲取token或者刪除賬號(hào)的方法
閑話少說(shuō),直接上碼
登陸developer賬號(hào),在app bundle ID的Capabilities里,打勾 Sign In with Apple .
打開Xcode 11.0 Beta或更新版本,在項(xiàng)目設(shè)置 - Signing Capabilities 里,開啟 Sign in with Apple 選項(xiàng)。
實(shí)現(xiàn)分四大部分:
在上面 ASAuthorizationControllerDelegate 的用戶通過(guò)驗(yàn)證的回調(diào)里,可以拿到 credential ,這里面有一些信息值得提下:
授權(quán)或者用戶信息是有可能被改變的,我們能做到就是盡早的檢測(cè)出這樣的改變,并做以應(yīng)對(duì)。
檢測(cè)授權(quán)的狀態(tài)需要記錄在上面所得到的
在 AppleDelegate 里,把之前存的用戶ID放到 ASAuthorizationAppleIDProvider 里驗(yàn)證即可,可以得到幾種用戶授權(quán)狀態(tài):
如果有錯(cuò)誤歡迎指出,也歡迎各種討論,謝????!