iOS13苹果登录的后台验证token(JAVA)

最近随着iOS的更新,苹果要求含有第三方登录的app必须实现苹果登录功能,在查询相关资料后整合进自己的项目中,再次记录下,也供大家借鉴。
以下是大致流程,挺简单的:
iOS13苹果登录的后台验证token(JAVA)_第1张图片
首先引入解析jwt的包:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>jwks-rsa</artifactId>
    <version>0.9.0</version>
</dependency>

直接贴代码:
1.向苹果后台获取公钥参数(后台发送http请求工具类请自行配置,json转换工具也请自行使用)

**HttpClientResult httpClientResult = null;
        try {
            httpClientResult = HttpClientUtils.doGet("https://appleid.apple.com/auth/keys");
        } catch (Exception e) {
            throw new SysException("向苹果发送请求获取公钥失败", e);
        }
        JSONObject jsonObject = JSONObject.parseObject(httpClientResult.getContent());
        String keys = jsonObject.getString("keys");
        JSONArray arr = JSONObject.parseArray(keys);
        JSONObject jsonObject1 = JSONObject.parseObject(arr.getString(0));**

ps 我们像苹果api获取的到的公钥参数格式如下(网上有很多对参数的解释):



```java
{"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

Jwk jwa = Jwk.fromValues(jsonObject1);
PublicKey publicKey = jwa.getPublicKey();

第三步,分割前台传过来的identifyToken(jwt格式的token)用base64解码使用:

if (identifyToken.split("\\.").length > 1) {
                String claim = new String(Base64.decodeBase64(jwt.split("\\.")[1]));
                String aud = JSONObject.parseObject(claim).get("aud").toString();
                String sub = JSONObject.parseObject(claim).get("sub").toString();
                return Utils.verify(publicKey, jwt, aud, sub);
            }

验证方法:
// 验证苹果公钥

public static String 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 "SUCCESS";
        }
        return "FAIL";
    } catch (ExpiredJwtException e) {
       throw new SysException("苹果token过期", e);
    } catch (Exception e) {
        throw new SysException("苹果token非法", e);
    }
}

业务方法:

public String appleAuth(String jwt) {
        HttpClientResult httpClientResult = null;
        try {
            httpClientResult = HttpClientUtils.doGet("https://appleid.apple.com/auth/keys");
        } catch (Exception e) {
            throw new SysException("向苹果发送请求获取公钥失败", e);
        }
        JSONObject jsonObject = JSONObject.parseObject(httpClientResult.getContent());
        String keys = jsonObject.getString("keys");
        JSONArray arr = JSONObject.parseArray(keys);
        JSONObject jsonObject1 = JSONObject.parseObject(arr.getString(0));
        Jwk jwa = Jwk.fromValues(jsonObject1);
        try {
            // 生成苹果公钥
            PublicKey publicKey = jwa.getPublicKey();
//            String hearder = new String(Base64.decodeBase64(jwt.split("\\.")[0]));
            if (jwt.split("\\.").length > 1) {
                String claim = new String(Base64.decodeBase64(jwt.split("\\.")[1]));
                String aud = JSONObject.parseObject(claim).get("aud").toString();
                String sub = JSONObject.parseObject(claim).get("sub").toString();
                return Utils.verify(publicKey, jwt, aud, sub);
            }
            return "FAIL";
        } catch (InvalidPublicKeyException e) {
            throw new SysException("转换苹果公钥失败", e);
        }
    }

总结:找到4个参数调用验证方法即可。

你可能感兴趣的:(苹果ios13三方登录)