苹果AppId登录注册
苹果授权登陆方式
- PC/M端授权登陆,采用协议类似于oauth2协议
- App端授权登陆,提供两种后端验证方式
开发者后台配置
详细配置参考该文档,手把手教学
https://developer.okta.com/blog/2019/06/04/what-the-heck-is-sign-in-with-apple
1、 PC/M接入方式
- https://appleid.apple.com/auth/authorize?response_type=code&client_id=&redirect_uri=&state=1234
- 参考上面的后台配置,其中client_id对应的是Services ID,redirect_uri就是后台配置的接收code码的地址
2、APP端客户端授权登陆功能开发,可以参考如下文档
- https://www.jianshu.com/p/23b46dea2076
重点讲解苹果授权登陆后端如何验证
针对后端验证苹果提供了两种验证方式,一种是基于JWT的算法验证,另外一种是基于授权码的验证
1、基于JWT的算法验证
- 使用到的Apple公钥接口:https://appleid.apple.com/auth/keys
- 详细接口文档说明参见:https://developer.apple.com/documentation/signinwithapplerestapi/fetch_apple_s_public_key_for_verifying_token_signature
- 接口返回值:
{
"keys": [{"kty": "RSA", "kid": "AIDOPK1","use": "sig","alg": "RS256","n": "lxrwmuYSAsTfn-lUu4goZSXBD9ackM9OJuwUVQHmbZo6GW4Fu_auUdN5zI7Y1dEDfgt7m7QXWbHuMD01HLnD4eRtY-RNwCWdjNfEaY_esUPY3OVMrNDI15Ns13xspWS3q-13kdGv9jHI28P87RvMpjz_JCpQ5IM44oSyRnYtVJO-320SB8E2Bw92pmrenbp67KRUzTEVfGU4-obP5RZ09OxvCr1io4KJvEOjDJuuoClF66AT72WymtoMdwzUmhINjR0XSqK6H0MdWsjw7ysyd_JhmqX5CAaT9Pgi0J8lU_pcl215oANqjy7Ob-VMhug9eGyxAWVfu_1u6QJKePlE-w","e": "AQAB"}
]
}
kid,为密钥id标识,签名算法采用的是RS256(RSA 256 + SHA 256),kty常量标识使用RSA签名算法,其公钥参数为n和e,其值采用了BASE64编码,使用时需要先解码
- 使用方式:APP内苹果授权登陆会提供如下几个参数:userID、email、fullName、authorizationCode、 identityToken
- userID:授权的用户唯一标识
- email、fullName:授权的用户资料
- authorizationCode:授权code
- identityToken:授权用户的JWT凭证
下面针对identityToken后端验证做简要说明:
- identityToken参考样例:
// jwt 格式
eyJraWQiOiJBSURPUEsxIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiY29tLnNreW1pbmcuZGV2aWNlbW9uaXRvciIsImV4cCI6MTU2NTY2ODA4NiwiaWF0IjoxNTY1NjY3NDg2LCJzdWIiOiIwMDEyNDcuOTNiM2E3OTlhN2M4NGMwY2I0NmNkMDhmMTAwNzk3ZjIuMDcwNCIsImNfaGFzaCI6Ik9oMmFtOWVNTldWWTNkcTVKbUNsYmciLCJhdXRoX3RpbWUiOjE1NjU2Njc0ODZ9.e-pdwK4iKWErr_Gcpkzo8JNi_MWh7OMnA15FvyOXQxTx0GsXzFT3qE3DmXqAar96nx3EqsHI1Qgquqt2ogyj-lLijK_46ifckdqPjncTEGzVWkNTX8uhY7M867B6aUnmR7u-cf2HsmhXrvgsJLGp2TzCI3oTp-kskBOeCPMyTxzNURuYe8zabBlUy6FDNIPeZwZXZqU0Fr3riv2k1NkGx5MqFdUq3z5mNfmWbIAuU64Z3yKhaqwGd2tey1Xxs4hHa786OeYFF3n7G5h-4kQ4lf163G6I5BU0etCRSYVKqjq-OL-8z8dHNqvTJtAYanB3OHNWCHevJFHJ2nWOTT3sbw// header 解码
{"kid":"AIDOPK1","alg":"RS256"} 其中kid对应上文说的密钥id// claims 解码
{"iss":"https://appleid.apple.com","aud":"com.skyming.devicemonitor","exp":1565668086,"iat":1565667486,"sub":"001247.93b3a799a7c84c0cb46cd08f100797f2.0704","c_hash":"Oh2am9eMNWVY3dq5JmClbg","auth_time":1565667486
}其中 iss标识是苹果签发的,aud是接收者的APP ID,该token的有效期是10分钟,sub就是用户的唯一标识
如何验证?
首先通过identityToken中的header中的kid,然后结合苹果获取公钥的接口,拿到相应的n和e的值,然后通过下面这个方法构建RSA公钥public RSAPublicKeySpec build(String n, String e) { BigInteger modulus = new BigInteger(1, Base64.decodeBase64(n));BigInteger publicExponent = new BigInteger(1, Base64.decodeBase64(e));return new RSAPublicKeySpec(modulus, publicExponent);
}通过下面这个方法验证JWT的有效性
public int verify(PublicKey key, String jwt, String audience, String subject) { JwtParser jwtParser = Jwts.parser().setSigningKey(key); jwtParser.requireIssuer("https://appleid.apple.com"); jwtParser.requireAudience(audience);jwtParser.requireSubject(subject); try {Jws<Claims> claim = jwtParser.parseClaimsJws(jwt);if (claim != null && claim.getBody().containsKey("auth_time")) { return GlobalCode.SUCCESS; } return GlobalCode.THIRD_AUTH_CODE_INVALID;} catch (ExpiredJwtException e) { log.error("apple identityToken expired", e);return GlobalCode.THIRD_AUTH_CODE_INVALID;} catch (Exception e) {log.error("apple identityToken illegal", e);return GlobalCode.FAIL_ILLEGAL_REQ;}
}使用的JWT工具库为:
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency>
2、基于授权码的后端验证
- 首先需要了解如何构建client_secret,详细文档可以参考如下两个:
- https://developer.okta.com/blog/2019/06/04/what-the-heck-is-sign-in-with-apple
- https://developer.apple.com/documentation/signinwithapplerestapi/generate_and_validate_tokens
首先说下client_secret的构建方法:
先在后台生成授权应用APP ID的密钥KEY文件,然后下载密钥文件格式样例:-----BEGIN PRIVATE KEY-----BASE64编码后的密钥
-----END PRIVATE KEY-----public byte[] readKey() throws Exception {String temp = "密钥文件中间的编码字符串";return Base64.decodeBase64(temp);
}构建client_secret关键代码:String client_id = "..."; // 被授权的APP ID
Map<String, Object> header = new HashMap<String, Object>();
header.put("kid", "密钥id"); // 参考后台配置
Map<String, Object> claims = new HashMap<String, Object>();
claims.put("iss", "team id"); // 参考后台配置 team id
long now = System.currentTimeMillis() / 1000;
claims.put("iat", now);
claims.put("exp", now + 86400 * 30); // 最长半年,单位秒
claims.put("aud", "https://appleid.apple.com"); // 默认值
claims.put("sub", client_id);
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(readKey());
KeyFactory keyFactory = KeyFactory.getInstance("EC");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
String client_secret = Jwts.builder().setHeader(header).setClaims(claims).signWith(SignatureAlgorithm.ES256, privateKey).compact();
如何验证?
String url = "https://appleid.apple.com/auth/token";
// POST 请求
HttpSynClient client = new HttpSynClient(5000, 5000, 5000, 20);
Map<String, String> form = new HashMap<String, String>();
form.put("client_id", client_id);
form.put("client_secret", client_secret);
form.put("code", code);form.put("grant_type","authorization_code");
form.put("redirect_uri", redirectUrl);
HttpResponse result = client.excutePost(url, form);
System.out.println(result);
返回值样例:
{"access_token":"a0996b16cfb674c0eb0d29194c880455b.0.nsww.5fi5MVC-i3AVNhddrNg7Qw",
"token_type":"Bearer",
"expires_in":3600,
"refresh_token":"r9ee922f1c8b048208037f78cd7dfc91a.0.nsww.KlV2TeFlTr7YDdZ0KtvEQQ",
"id_token":"eyJraWQiOiJBSURPUEsxIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiY29tLnNreW1pbmcuYXBwbGVsb2dpbmRlbW8iLCJleHAiOjE1NjU2NjU1OTQsImlhdCI6MTU2NTY2NDk5NCwic3ViIjoiMDAwMjY2LmRiZTg2NWIwYWE3MjRlMWM4ODM5MDIwOWI5YzdkNjk1LjAyNTYiLCJhdF9oYXNoIjoiR0ZmODhlX1ptc0pqQ2VkZzJXem85ZyIsImF1dGhfdGltZSI6MTU2NTY2NDk2M30.J6XFWmbr0a1hkJszAKM2wevJF57yZt-MoyZNI9QF76dHfJvAmFO9_RP9-tz4pN4ua3BuSJpUbwzT2xFD_rBjsNWkU-ZhuSAONdAnCtK2Vbc2AYEH9n7lB2PnOE1mX5HwY-dI9dqS9AdU4S_CjzTGnvFqC9H5pt6LVoCF4N9dFfQnh2w7jQrjTic_JvbgJT5m7vLzRx-eRnlxQIifEsHDbudzi3yg7XC9OL9QBiTyHdCQvRdsyRLrewJT6QZmi6kEWrV9E21WPC6qJMsaIfGik44UgPOnNnjdxKPzxUAa-Lo1HAzvHcAX5i047T01ltqvHbtsJEZxAB6okmwco78JQA"
}
其中id_token是一个JWT,其中claims中的sub就是授权的用户唯一标识,该token也可以使用上述的验证方法进行有效性验证,另外授权code是有时效性的,且使用一次即失效
苹果AppId登录注册相关推荐
- Axure经典实例高保真交互下载(微信元件高保真交互库+微信原型交互+安卓设备模板含登录注册引导欢迎流程+ios苹果设备模板)
作品介绍:原型内容包括:微信小程序原件库.视觉规范.基础组件.操作反馈.导航搜索.ios机型设备模板.常用元素.安卓手机设备模板包含注册登录.欢迎引导页等 Axure兼容版本:8.0 和9.0 Axu ...
- Apple Sign in with Apple(苹果授权登录PHP)
Apple Sign in with Apple(苹果授权登录PHP) 文章目录 Apple Sign in with Apple(苹果授权登录PHP) 一.登录Apple Developer 二.创 ...
- 苹果授权登录 jwt node 解码
苹果授权登录 jwt node 解码 const jwt_decode = require('jwt-decode') const NodeRSA = require('node-rsa'); con ...
- php微信网页开发实现自动登录注册功能实例
功能:自动登录注册功能 描述:php实现微信网页自动登录注册功能 范围:适用于所有php版本 功能实例 $token = $_COOKIE['wechat_token']; if($token){// ...
- 苹果手机怎么创建php,怎么在苹果官网注册Apple ID?在网页上创建Apple ID教程
如何在网页上创建Apple ID呢?Apple ID账号是苹果手机上面常常使用的一个账号,很多人可能注册时都是在苹果手机上面注册Apple ID账号的,其实除了苹果手机注册以外,我们还可以直接通过网页 ...
- 苹果开发者账号注册申请流程
苹果开发者账号的注册过程比较复杂,和大家分享一下过程和细节,以免大家走了弯路. 1.登陆苹果开发者官网页面 https://developer.apple.com/programs/ios/ 2.点击 ...
- Sign In with Apple - 使用苹果账号登录你的应用
编辑:老峰,作者:KANGZUBIN 来源:小专栏<WWDC19 内参> 苹果在 9 月 12 号更新了审核指南,加入 4.8 Sign in with Apple 一条,要求所有使用 第 ...
- 2017最新苹果 APPLE ID注册流程
不管你是苹果开发者还是苹果爱好者,只要你手中有苹果的终端(IPHONE .IPAD .ITouch,MAC电脑) 你想用苹果的一些服务,你就必须要申请苹果APPLE ID,才能享受到苹果提供高品质的服 ...
- 2015年最新苹果开发者账号注册流程详解
苹果开发者账号的注册过程比较复杂,和大家分享一下过程和细节,以免大家走了弯路. 1.登陆苹果开发者官网页面 https://developer.apple.com/programs/ios/ 2.点击 ...
- 2016年最新苹果开发者账号注册流程详解(公司账号篇)
随着苹果规定金融/理财类应用需要使用公司开发者账号上传,并进一步加大对此类问题的审核力度,公司开发者账号开始呈现出炙手可热之势! 不过,公司开发者账号的注册流程着实复杂--不仅要填写公司的D-U-N- ...
最新文章
- 最全整理 | 万字长文综述目标检测领域,您要的,都在这里!
- 毕业设计:Springboot实现疫情宿舍学生管理系统
- spoon kettle连接数据库失败解决方法
- WinAPI: Pie - 绘制饼图
- mysql死锁释放时间参数_由FTWRL导致的MySQL从库死锁分析及参数深究
- 微软MCITP系列课程(八)文件服务器及磁盘配额
- oracle 取第三大的值,Oracle 常见的几种访问提取数据的方式!
- 如何卸载bytefence anti-malware
- php+中午截取,php中截取中文字符串的代码小结
- tkinter 实现简单登录窗
- Android SQLite封装sql语句、查看数据库
- 如何将MID音乐转换成MP3
- Jenkinsfile脚本实现master、slave节点(agent)共享内容
- Python教学视频(五)顺序结构练习
- java中nextToken,Java StringTokenizer nextToken()用法及代碼示例
- 《实用软件工程答案》张海涛人民邮电出版社
- openmp多线程简单编程
- matlab输出的特征向量,关于matlab中的eig函数(求特征值和特征向量)(最新整理)
- 《数据结构》实验三:栈和队列实验 (实验报告)
- Inspection info: Reports octal integer literals. Some coding standards prohibit the use of octal...