Apple登录可以看做第三方登录的一种,即使用Apple ID登录,前提是你已经有了苹果开发者账号,直接进入主题吧。

添加App IDs

填写Bundle ID

勾选“Sign In with Apple”

创建Key
苹果将使用公钥/私钥对作为OAuth客户端机密,其中客户端机密实际上是一个签名的JWT,下一步需要向Apple注册新的私钥。

创建完成后会生成一个Key ID以及Key文件。下载key文件,其实就是一个.p8文件,双击可打开这个文件里面有需要的key,这个文件很重要,而且只能下载一次,请妥善保存!!!

生成客户端密钥(Client Secret)

苹果要求您自己从私钥中导出客户端密钥,而不是静态客户端密钥。他们使用JWT标准,使用带有P-256曲线和SHA256散列的椭圆曲线算法。换句话说,他们使用ES256JWT算法。有些JWT库不支持椭圆曲线方法,所以在开始尝试之前,请确保您的库支持椭圆曲线。RubyJWT库支持这种算法,因此我们将使用它来生成秘密。

首先,确保已安装Ruby,然后从命令行运行以下命令来安装JWT gem:

gem install jwt

根据上面准备的 Bundle IDTeam IDKey IDAuthKey_xxx.p8就可以生成client_secret(客户端密钥),我们简单创建一个txt文件,命名为secret_gen,然后将后缀改为.rb,即secret_gen.rb。模版内容如下:

require 'jwt'key_file = ''
team_id = ''
client_id = ''
key_id = ''ecdsa_key = OpenSSL::PKey::EC.new IO.read key_fileheaders = {'kid' => key_id
}claims = {'iss' => team_id,'iat' => Time.now.to_i,'exp' => Time.now.to_i + 86400*180,'aud' => 'https://appleid.apple.com','sub' => client_id,
}token = JWT.encode claims, ecdsa_key, 'ES256', headersputs token

该代码使用ES256算法生成JWT,其中包含少量声明。JWT将在6个月内到期,这是苹果允许的最长使用期限。如果您在每次用户进行身份验证时都生成一个新的客户端密钥JWT,那么您应该使用更短的到期日期,但这允许我们生成一次密钥并在示例应用程序中轻松使用。

这里将用到我们已经准备好的四个数据,现在您可以从命令行运行它,它将输出一个JWT:

ruby xxx/xx/xx/secret_gen.rb


这个eyJra.....RuAQ就是我们需要的客户端密钥,接下来我们验证下这个密钥是否有效。

在项目中配置苹果登录

首先导入头文件#import <AuthenticationServices/AuthenticationServices.h>,然后调起苹果授权页面

    if (@available(iOS 13.0, *)) {ASAuthorizationAppleIDProvider *appleIdProvider = [[ASAuthorizationAppleIDProvider alloc] init];ASAuthorizationAppleIDRequest *authAppleIDRequest = [appleIdProvider createRequest];/*//慎用 ASAuthorizationPasswordRequest//当启用ASAuthorizationPasswordRequest且停止使用Apple ID(真机-设置-账户-密码与安全性-使用您Apple ID的App-App列表-停止使用 Apple ID, 如果KeyChain里面没有登录信息且重新使用苹果授权登录(Sign in with Apple)会报未知错误ASAuthorizationPasswordRequest* authPasswordRequest = [[[ASAuthorizationPasswordProvider alloc] init] createRequest];NSMutableArray <ASAuthorizationRequest*> * array = [NSMutableArray arrayWithCapacity:2];if(authAppleIDRequest) [array addObject:authAppleIDRequest];if(authPasswordRequest) [array addObject:authPasswordRequest];NSArray <ASAuthorizationRequest*> * requests = [array copy];ASAuthorizationController* authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:requests];*/authAppleIDRequest.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];//由ASAuthorizationAppleIDProvider创建的授权请求 管理授权请求的控制器ASAuthorizationController* authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[authAppleIDRequest]];//设置授权控制器通知授权请求的成功与失败的代理authorizationController.delegate = self;//设置提供 展示上下文的代理,在这个上下文中 系统可以展示授权界面给用户authorizationController.presentationContextProvider = self;//在控制器初始化期间启动授权流[authorizationController performRequests];}

代理回调ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding

//授权成功
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0))
{NSString *userID = nil;NSString *userName = nil;NSString *userEmail = nil;EVAppleLoginCredentialModel *model = [[EVAppleLoginCredentialModel alloc] init];if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {ASAuthorizationAppleIDCredential *credential = authorization.credential;//苹果用户唯一标识符,该值在同一个开发者账号下的所有App下是一样的,开发者可以用该唯一标识符与自己后台系统的账号体系绑定起来。userID = credential.user;//苹果用户信息 如果授权过,无法再次获取该信息userEmail = credential.email;NSPersonNameComponents *fullName = credential.fullName;userName = [NSString stringWithFormat:@"%@%@", fullName.familyName, fullName.givenName];//用于判断当前登录的苹果账号是否是一个真实用户,取值有:unsupported、unknown、likelyRealASUserDetectionStatus realUserStatus = credential.realUserStatus;//服务器验证需要使用的参数NSString *authorizationCode = [[NSString alloc] initWithData:credential.authorizationCode encoding:NSUTF8StringEncoding];NSString *identityToken = [[NSString alloc] initWithData:credential.identityToken encoding:NSUTF8StringEncoding];NSLog(@"authorization [ASAuthorizationAppleIDCredential] successfully");NSLog(@"authorization userID: %@", userID);NSLog(@"authorization userName: %@", userName);NSLog(@"authorization userEmail: %@", userEmail);NSLog(@"authorization realUserStatus: %@", @(realUserStatus));NSLog(@"authorization authorizationCode: %@", authorizationCode);NSLog(@"authorization identityToken: %@", identityToken);} else if ([authorization.credential isKindOfClass:[ASPasswordCredential class]]) {//用户登录使用现有的密码凭证ASPasswordCredential *passwordCredential = authorization.credential;//密码凭证对象的用户标识 用户的唯一标识和密码userID = passwordCredential.user;NSString *password = passwordCredential.password;NSLog(@"authorization [ASPasswordCredential] successfully");NSLog(@"authorization userID: %@", userID);NSLog(@"authorization password: %@", password);model.user = passwordCredential.user;userName = @"";userEmail = @"";} else {assert(0);}//数据校验通过后,将这些数据发送给服务器进行验证,等待服务器的回应//如果用户选择隐藏邮箱的,email获取不到,其他数据正常,服务端匹配标准userIDif (![ZJUtils isEmpty:userID]) {//在授权成功的回调中拿到服务器所需要的参数传给后台//至此我们所需要做的已经完成了,看后台的验证就行了if (self.appleLoginBlock) {self.appleLoginBlock(0, @"苹果授权成功", model);}} else {//授权数据异常if (self.appleLoginBlock) {self.appleLoginBlock(-1, @"苹果授权失败", nil);}}
}//授权失败
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0))
{NSString *errorMsg = nil;UIWindow *window = [UIApplication sharedApplication].keyWindow;switch (error.code) {case ASAuthorizationErrorCanceled:errorMsg = @"用户取消了授权请求";break;case ASAuthorizationErrorFailed:errorMsg = @"授权请求失败";break;case ASAuthorizationErrorInvalidResponse:errorMsg = @"授权请求响应无效";break;case ASAuthorizationErrorNotHandled:errorMsg = @"未能处理授权请求";break;case ASAuthorizationErrorUnknown:errorMsg = @"授权请求失败未知原因";break;}NSLog(@"苹果授权状态:%@", errorMsg);
}#pragma mark ASAuthorizationControllerPresentationContextProviding
- (ASPresentationAnchor) presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller API_AVAILABLE(ios(13.0))
{return self.view.window;
}

- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization 回调中我们拿到 authorizationCode 作为验证的参数。

打开postman我们测试下:

https://appleid.apple.com/auth/token?client_id=xxx&client_secret=xxx&code=xxx&grant_type=authorization_code&redirect_uri=https://appleid.apple.com

到这里就基本完成了,其实苹果登录大部分工作都是后台在做,包括client_secret生成等,我们客户端只需要在拿到苹果授权的数据给后端就可以了,后端去做校验。

参考:What the Heck is Sign In with Apple?

Apple ID 登录相关推荐

  1. MAC重置密码时,使用Apple ID登录时 下发显示红字“连接到Apple ID”且点击下一步无反应

    MAC重置密码时,使用Apple ID登录时 下发显示红字"连接到Apple ID"且点击下一步无反应 如图 处理办法 说明一下 如图 处理办法 确认是否连网: 在终端里输入&qu ...

  2. [Apple]通过Apple ID登录App时提示“共享”和“隐藏”邮件地址的问题

    [Apple]通过Apple ID登录App时提示"共享"和"隐藏"邮件地址的问题 点击此处跳转 希望对您有所帮助.

  3. Cordova iOS 项目中微信/qq/Apple ID插件的安装以及登录的实现

    说明:我们在做项目的时候,往往会接入第三方登录,使用官方或者已经大神已经写好的插件,不仅节省时间,而且可以加快我们项目开发的进度,本文章记录我在工程中所用到的几个第三方登录,一方面为了防止时间长了忘记 ...

  4. iOS 11.3 显示:Apple ID 或将实现微信式扫码登陆

    点击上方"CSDN",选择"置顶公众号" 关键时刻,第一时间送达! 据外媒 9to5mac 近日报道,苹果似乎在筹备基于 "iCloud 个人数据&q ...

  5. 苹果开发者账号注册错误:关联的Apple ID国家/地区并不匹配

    今天在注册账号时发现苹果出了一个新的提示: Apple ID问题 您在"设置">"iTunes Store与AppStore"中关联的Apple ID国家 ...

  6. apple id两步验证服务器,如何开启 Apple ID 两步验证

    本期教学点: 开启 Apple ID 两步验证,减小 Apple ID 被盗风险,大大提高安全性. 首先打开 Safari 浏览器,在地址栏输入 appleid.apple.com. 点击右边&quo ...

  7. MacOS安装之:此Apple ID 未用于 App Store

    遇到此问题是你申请的苹果账号资料不完善导致的 进入苹果官方网站:Manage your Apple ID 登录你的ID,完善里面两项信息 Personal Information (个人信息) Pay ...

  8. 把Apple ID 账号改成QQ邮箱教程

    很多朋友在买了Apple ID 账号后想把之前绑定的邮箱改为自己的,但是不知道具体的一个操作方式,下面看看步骤: 1.前往 appleid.apple.com 并登录. 2.在"登录和安全& ...

  9. sharemouse切窗口就锁定了什么原因_iPhone 提示“Apple ID 已锁定”是什么原因?

    当我们在 iPhone 上登录或使用 Apple ID 时,可能会看到这样一条提示: "Apple ID 已锁定:处于安全原因,您的 Apple ID 已被锁定.若要解锁,必须验证您的身份. ...

最新文章

  1. 报名 | 数据新闻发展趋势与人才培养学术讲座(武汉)
  2. artDialog、Ztree 初体验
  3. windows7专业版_windows7专业版和旗舰版的区别
  4. 初识jvm-1.Java类的加载机制
  5. Spring Boot之HelloWorld
  6. React开发(152):注意替换路径
  7. Dialog 基本使用
  8. osea/ introduction
  9. Xilisoft iPad Magic Platinum for Mac如何制作铃声?将联系人传输到计算机/设备?
  10. 多人操作sqlite3数据库冲突问题解决方法
  11. 工程项目进度表excel模板_救命,每天都要做工作报告!Excel一键生成精美报告的技巧,必学!...
  12. Vue 做调查问卷简单实例
  13. 苹果客户端支付后,服务器端对数据进行二次验证接口开发
  14. 编译原理——自上而下的语法分析方法(LL分析法)
  15. 更改计算机用户名不能上网,电脑网络用户名改了连接不上怎么办
  16. VisualC++开发GIS系统
  17. 网页设计问卷调查的要点-适合初学者
  18. 计算机如何恢复桌面,如何恢复电脑原始桌面
  19. Spring Cloud Feign传输Header,并保证多线程情况下也适用
  20. dvd光盘安装linux系统,从单DVD光盘上安装openSUSE

热门文章

  1. The JSON value could not be converted to System.Int64
  2. 打印网页去掉不相关信息
  3. 初学Java多线程:线程简介
  4. 创业板、融资融券被寄予厚望
  5. 如何在电脑/手机上将JPEG图片保存为PDF?
  6. 服务器存储系统的模式,服务器的三种存储方式
  7. 小米air2se耳机只有一边有声音怎么办_不到200元 小米蓝牙耳机Air2 SE是真香党的选择吗?...
  8. 深入理解Java7.pdf
  9. [计算机网络]第二章——应用层
  10. 51单片机LCD1602显示电子时钟 带按键设置和星期显示