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. jvm的内存区域介绍

    什么是jvm? JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的 ...

  2. eclipse智能提示报错(to avoid the message, disable the...)

    然后这里可能会再报别的错误  我的做法是   再重新将 code recommenders 打开 ********************************** 为什么会出现 这样错误呢 ? 简 ...

  3. 使用element-ui中的el-upload组件时携带其他参数

    解决方法:// template <el-upload action="/api/oss/file/add" :headers="headers" // ...

  4. vue cli3 打包到tomcat上报错问题

    首先  项目打包步骤 1.vue config.js  添加 publicPath: './', // 公共路径 assetsDir:'static', 2.将代理注释掉 proxy 3.将hash需 ...

  5. Vue路由嵌套

    Vue路由嵌套 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  6. java玩转zip压缩包

    首先将相关jar包引入pom.xml中 <!-- 解压zip --> <dependency> <groupId>org.apache.ant</groupI ...

  7. linux 基础8-shell script

    1. 什么是shell script 1.1 介绍: 什么是 shell script (程序化脚本) 呢?就字面上的意义,我们将他分为两部份. 在『 shell 』部分,我们在bash当中已经提过了 ...

  8. Windows 下 mysql 安装

    mysql官网下载地址:https://downloads.mysql.com/archives/community/ 以5.7.20版本为例 首先安装包解压后,没有网上教程里面提到的data文件夹和 ...

  9. Python程序打包工具PyInstaller

    Python程序执行 py文件:直接提供源码,需要使用者自行安装Python并且安装依赖的各种库 pyc文件:pyc文件是Python解释器可以识别的二进制码,是跨平台的,需要使用者安装相应版本的Py ...

  10. PHP 获取上传文件的实际类型

    方案一: mime_content_type ( string $filename ) : string (PHP 4 >= 4.3.0, PHP 5, PHP 7) mime_content_ ...