2019年10月9号  IOS端新增Sign in with Apple

IOS真是世界上最垃圾的语言,没有之一,苹果是世界上最垃圾的公司,没有之一

关于Sign in with Apple 苹果官方给的文档几乎不提后台如何验证,只是画了几张图,客户端把一些参数传递给后台,后台使用这些参数去请求 IOS验证服务器 验证成功 OK 听起来很简单吧

mmp 1.前台给的参数如何解析?

mmp 2.参数怎么传给IOS服务器?

mmp 3.返回什么就算解析成功?

一概不提,最起码给个demo啊

翻遍了网上的资源,最终找到一个还算过的去的 https://blog.csdn.net/wpf199402076118/article/details/99677412

博客中大致说了两种验证方式:

1.JWT 验证 博主也贴出了代码,但是你会发现,代码跑不通,不知道是代码没贴全还是什么鬼,两个方法你不知到怎么调用

2.授权码验证 需要的很多字段你不知道该从哪里获取,前台无法传递给你

经过无数次的试验和无数次的抓狂,最终有了下面的垃圾代码,我总觉得哪里还是有问题,代码贴出来问题接下来说

public static String verify(String jwt, String audience, String subject) throws Exception {
String strkey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlxrwmuYSAsTfn+lUu4goZSXBD9ackM9OJuwUVQHmbZo6GW4Fu/auUdN5zI7Y1dEDfgt7m7QXWbHuMD01HLnD4eRtY+RNwCWdjNfEaY/esUPY3OVMrNDI15Ns13xspWS3q+13kdGv9jHI28P87RvMpjz/JCpQ5IM44oSyRnYtVJO+320SB8E2Bw92pmrenbp67KRUzTEVfGU4+obP5RZ09OxvCr1io4KJvEOjDJuuoClF66AT72WymtoMdwzUmhINjR0XSqK6H0MdWsjw7ysyd/JhmqX5CAaT9Pgi0J8lU/pcl215oANqjy7Ob+VMhug9eGyxAWVfu/1u6QJKePlE+wIDAQAB";
PublicKey publicKey = getPublicKey(strkey);
JwtParser jwtParser = Jwts.parser().setSigningKey(publicKey);
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 "SUCCESS";
}
return "FIALD";
} catch (ExpiredJwtException e) {
log.error("apple identityToken expired", e);
return "FIALD";
} catch (Exception e) {
log.error("apple identityToken illegal", e);
return "FIALD";
}
} /**
* String转公钥PublicKey
* @param key
* @return
* @throws Exception
*/
public static PublicKey getPublicKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = (new BASE64Decoder()).decodeBuffer(key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}

说下如何验证

1.IOS客户端会调用苹果的授权登录一系列操作成功后会从苹果那获取一些很基本的信息 比如唯一的userId,一个jwt格式的验证字符串 identityToken,邮箱 等

2.客户端授权验证成功后调用后台接口进行验证

3.后台解析 jwt的这个字符串,jwt格式的字符串用 “ . ”’ 把整个信息分割成三部分,第一部分是 header 包含了 编码格式 和秘钥 id ,第二部分就是一些验证信息 授权人是谁啊 有效时间啊  第三部分是一二部分加起来后再加密的一个东西,这块我也没搞懂,第三部分的解析我到现在也不懂

4. jwt 的 header 和 claim(第二部分) 都是使用Base64编码过的 使用是需要解码

第一部分解析出来的

{
"kid": "AIDOPK1",
"alg": "RS256"
}

第二部分解析出来的

{
"iss": "https://appleid.apple.com",
"aud": "**********",
"exp": 1570617356,
"iat": 1570616756,
"sub": "00*****1790047f40335c6c1a.0641",
"c_hash": "eqOdpr_**TyHiRymHbPQ",
"auth_time": 1570616756
}

5.第二部分的解码可以获取到两个有效信息   aud 和 sub 这两个在验证的时候需要使用

6.验证方法中的key 这个key本来是从苹果提供的一个get接口中获取的但是获取到的格式是下面的东西

{
"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"
}
]
}

这个东西怎么用?我没要找到具体的描述,但是网上网站可以将这个东西转换正 PublicKey 至于 java代码中如何转换我也没找到,还望找的同学告知下 网上转换后得到的是是一个字符串 通过一下的方法可以转换成 PublicKey

public static PublicKey getPublicKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = (new BASE64Decoder()).decodeBuffer(key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}

7.验证 验证字符串的有效时间是5分钟

补充:

String jwt = thirdLoginReq.getIdentityToken();
String decode = Base64.decoded(jwt.split("\\.")[1]);
String substring = decode.substring(0, decode.indexOf("}")+1);
JSONObject jsonObject = JSON.parseObject(substring);
String sub = jsonObject.getString("sub");
String aud = jsonObject.getString("aud");

使用到的jar

<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>

更新 20191010 19:00

经过查阅资料发现可以将 苹果返回的公钥转化成 publicKey 需要引入jar包

<dependency>
<groupId>com.auth0</groupId>
<artifactId>jwks-rsa</artifactId>
<version>0.9.0</version>
</dependency>
     String urlData = getUrlData("https://appleid.apple.com/auth/keys");
Map maps = (Map)JSON.parse(urlData);
List keys = (List<Map>)maps.get("keys");
Map o = (Map) keys.get(0);
Jwk jwa = Jwk.fromValues(o);
try {
PublicKey publicKey = jwa.getPublicKey();
} catch (InvalidPublicKeyException e) {
e.printStackTrace();
}

关于Sign in with Apple 后台验证的一些记录的更多相关文章

  1. Sign in with Apple 流程总结

    流程图 相关说明 UserId 与用户的 Apple Id 一一对应.在同一个开发帐号下的所有 app 里,获取到的值都一样. IdentityToken identityToken 是一个 Json ...

  2. sign in with apple后端校验(java)

    最近新开发的ios平台的app在提审的时候,被拒了,原因是app上如果有接第三方登陆(比如,微信,微博,facebook等),那就必须要接apple id登陆,坑爹~苹果霸权啊!然而没办法,靠他吃饭, ...

  3. SpringMVC学习系列-后记 结合SpringMVC和Hibernate-validator,根据后台验证规则自动生成前台的js验证代码

    在SpringMVC学习系列(6) 之 数据验证中我们已经学习了如何结合Hibernate-validator进行后台的数据合法性验证,但是通常来说后台验证只是第二道保险,为了更好的用户体验会现在前端 ...

  4. ASP.NET开发中主要的字符验证方法-JS验证、正则表达式、验证控件、后台验证

    ASP.NET开发中主要的字符验证方法-JS验证.正则表达式.验证控件.后台验证 2012年03月19日 星期一 下午 8:53 在ASP.NET开发中主要的验证方法收藏 <1>使用JS验 ...

  5. c#后台验证

    #region 后台验证 panda /// 验证电话号码的主要代码如下: public bool IsTelephone(string str_telephone) { return System. ...

  6. (转)jquery.validate.js 的 remote 后台验证

    之前已经有一篇关于jquery.validate.js验证的文章,还不太理解的可以先看看:jQuery Validate 表单验证(这篇文章只是介绍了一下如何实现前台验证,并没有涉及后台验证remot ...

  7. 表单数据验证方法(二)——ASP.NET后台验证

    昨天写了一下关于如何在前台快捷实现表单数据验证的方法,今天接着昨天的,把后台实现数据验证的方法记录一下.先说明一下哈,我用的是asp.net,所以后台验证方法也是基于.net mvc来做的. 好了,闲 ...

  8. JavaEE 之 后台验证+拦截器

    1.Validator后台验证 a.在web.xml中配置 <listener> <listener-class>org.springframework.web.context ...

  9. asp.net core 图片验证码,后台验证

    验证方法: public static string VerificationCodeCacheFormat="vcode_cache_{0}"; public IActionRe ...

随机推荐

  1. 数据库及MYSQL基础(3)-JDBC

    教学视频链接:https://edu.aliyun.com/course/1694?spm=5176.11400004.0.0.29254768sg2H5P 程序文件链接:https://pan.ba ...

  2. 初学VUE 走马灯效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. vue兄弟组件的传值eventbus

    注:当在a.vue组件上触发点击事件时,就会触发bus上监听的事件,而bus事件监听在b.vue里面,这个时候就会触发b.vue 上的事件监听,而通过回调函数,就可以拿到a.vue组件传过来的数据,从 ...

  4. Linux环境下Redis安装和常见问题的解决

    Redis是一款非常非常非常好用的缓存数据库,在保存需要定期更新的Token值,或者在保证高并发安全可靠性的场景下,基本上说是必用了. 安装过好多次Redis了,也用过阿里云Redis数据库,但是每次 ...

  5. TreeMap源码实现类中文全解析

    /** * 基于红黑树(Red-Black tree)的 NavigableMap 实现.该映射根据其键的自然顺序进行排序, * 或者根据创建映射时提供的Comparator 进行排序,具体取决于使用 ...

  6. 【leetcode】575. Distribute Candies

    原题 Given an integer array with even length, where different numbers in this array represent differen ...

  7. CentOS7数据库架构之NFS+heartbeat+DRBD(亲测,详解)

    目录 参考文档 理论概述 DRBD 架构 NFS 架构部署 部署DRBD 部署heartbeat 部署NFS及配合heartbeat nfs切记要挂载到别的机器上不要为了省事,省机器 参考文档 htt ...

  8. SPFA找负环(DFS) luogu3385

    SPFA找负环的基本思路就是如果一个点被访问两次说明成环,如果第二次访问时所用路径比第一次短说明可以通过一直跑这个圈将权值减为负无穷,存在负环 有bfs和dfs两种写法,看了一些博客,在bfs和dfs ...

  9. PAT Baisc 1079 延迟的回文数 (20 分)

    给定一个 k+1 位的正整数 N,写成 a​k​​⋯a​1​​a​0​​ 的形式,其中对所有 i 有 0 且 a​k​​>0.N 被称为一个回文数,当且仅当对所有 i 有 a​i​​=a​k−i ...

  10. Linux教程 网络管理命令Netstat的使用

    Netstat(network statistics) 网络统计命令是一个命令行工具,用于监视网络出入的连接,路由表以接口统计等.Netstat 在所有的Unix或者Linux系统,Windows系统 ...