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. (三)easyUI之树形组件

    一.同步树 1.1 概念 所有节点一次性加载完成 1.2 案例 1.2.1 数据库设计 1.2.2 编码 index.jsp <%@ page language="java" ...

  2. JFinal(2)JFinal 学习资料

    JFinal 学习资料 :http://pan.baidu.com/s/1hsOcQ0G 密码:7lq3 , jfinal社区收费会员内部部分资料,博主网络搜集而来

  3. [Vuex系列] - Mutation的具体用法

    更改 Vuex 的 store 中的状态的唯一方法是提交 mutation.Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 ...

  4. FastDFS高可用集群架构配置搭建及使用

    一,概述FastDFS 是一个开源的高性能分布式文件系统(DFS). 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡.FastDFS 系统有三个角色:跟踪服务器(Tracker ...

  5. S2-048

    前言 S2-048漏洞和struts2-struts1-plugin插件有关,该插件用于将Struts1的action也能在struts2上运行,提高兼容性(作用是我猜的~) 正文 我们先看下这个插件 ...

  6. 关于Objective C的私有函数

    (1)很多从其他语言(例如C++)转到objective c的初学者,往往会问到一个问题,如何定义类的私有函数?这里的“私有函数”指的是,某个函数只能在类的内部使用,不能在类的外部,或者派生类内部使用 ...

  7. C语言对齐、补齐

    加快CPU读取数据的速度 aligned(n) 让所作用的结构成员对齐在n字节自然边界上.如果结构中有成员的长度大于n,则按照最大成员的长度来对齐 struct s { char c; int i; ...

  8. [LeetCode] 15. 3Sum ☆☆☆(3数和为0)

    描述 Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Fi ...

  9. 页面使用element-tree

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

  10. libssh2--ssh2实例

    #include "libssh2_config.h"#include<libssh2.h>#include<libssh2_sftp.h> 上述为所包含必 ...