苹果apple账号授权登录第三方APP

中文官方文档
代码参考
代码参考 行得通

简单的就是:将前端传来的identity转成用户信息,获取公钥,前两者组装校验

1.获取第一把公钥  https://appleid.apple.com/auth/keys
    {  "keys": [
       {      
          "kty": "RSA",      
          "kid": "86D88Kf",      
          "use": "sig",      
          "alg": "RS256",      
          "n": "iGaLqP6y-SJCCBq5Hv6pGDbG_SQ11MNjH7rWHcCFYz4hGwHC4lcSurTlV8u3avoVNM8jXevG1Iu1SY11qInqUvjJur--hghr1b56OPJu6H1iKulSxGjEIyDP6c5BdE1uwprYyr4IO9th8fOwCPygjLFrh44XEGbDIFeImwvBAGOhmMB2AD1n1KviyNsH0bEB7phQtiLk-ILjv1bORSRl8AK677-1T8isGfHKXGZ_ZGtStDe7Lu0Ihp8zoUt59kx2o9uWpROkzF56ypresiIl4WprClRCjz8x6cPZXU2qNWhu71TQvUFwvIvbkE1oYaJMb0jcOTmBRZA2QuYw-zHLwQ",      
          "e": "AQAB"   
       },    
       {      
       	  "kty": "RSA",      
       	  "kid": "eXaunmL",     
       	   "use": "sig",      
       	   "alg": "RS256",      
       	   "n": "4dGQ7bQK8LgILOdLsYzfZjkEAoQeVC_aqyc8GC6RX7dq_KvRAQAWPvkam8VQv4GK5T4ogklEKEvj5ISBamdDNq1n52TpxQwI2EqxSk7I9fKPKhRt4F8-2yETlYvye-2s6NeWJim0KBtOVrk0gWvEDgd6WOqJl_yt5WBISvILNyVg1qAAM8JeX6dRPosahRVDjA52G2X-Tip84wqwyRpUlq2ybzcLh3zyhCitBOebiRWDQfG26EH9lTlJhll-p_Dg8vAXxJLIJ4SNLcqgFeZe4OfHLgdzMvxXZJnPp_VgmkcpUdRotazKZumj6dBPcXI_XID4Z4Z3OM1KrZPJNdUhxw",      
       	   "e": "AQAB"    
       	 }  
       ]
    }
     
2.前端传来的jwt,也叫identity(三段式格式),取第二段解码,获取用户信息,aud,sub等,见下面截图
3.根据公钥和第二段解码验证时间是否有效



前端传来的东东
idnetityToken:
   eyJraWQiOiJlWGF1bm1MIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiY29tLm5lYnVsYS54aW5neXVuY2hvbmciLCJleHAiOjE1OTU5MDIyODksImlhdCI6MTU5NTkwMTY4OSwic3ViIjoiMDAxMDQxLjNiNmU4MDFkMjc1NTQ2MmE4NWNiOWNhOTRkYmI2NmNmLjA2MTkiLCJjX2hhc2giOiJUazJ0a0wwMmpmUUNFbTZ4Sk9heE5BIiwiZW1haWwiOiJsaXJvbmd0YW5vNjAzQGljbG91ZC5jb20iLCJlbWFpbF92ZXJpZmllZCI6InRydWUiLCJhdXRoX3RpbWUiOjE1OTU5MDE2ODksIm5vbmNlX3N1cHBvcnRlZCI6dHJ1ZX0.fIvXm93mS6AzgtBfcEPj67U0OWxJ1EviS1c3uTR3VnnENLiZih0dyD5b9iXXkKTs9oCpXNzqAedgoHGbX1BUeTyyFI9aWRagS3QO2PusYmKAqiiAgY04jXkl01ThG3apy3sCVWMGEA-FxTZvD8Ku7E9VjHlB9zWGIlsiPzOLlwi9USh_teO5MMChtdbl1sqo9GTKKcZSF0psE2VS0UepAVSA1gdBRq8SU8GOGYdLhV1Ze2TY8_sDUENlrIY74EbA7kEc46WslPHCLPUjT0tAd-vyIo0cB4mJ277jM1MTQvjtT4NGgYwlkJf4TLag7Hz6CNL972n0yWyglgL2HVPJfQ

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

package com.nebula.microservice.authorization.user.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.codec.binary.Base64;
import org.springframework.util.Base64Utils;
import org.springframework.web.client.RestTemplate;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.RSAPublicKeySpec;

@Log4j2
public class AppleUtil {
    /**
     * 解密个人信息
     *
     * @param identityToken APP获取的identityToken
     *
     * @return 解密参数:失败返回null  sub就是用户id,用户昵称需要前端传过来
     */
    public static JSONObject verify(String identityToken) {
        try {
            String[] identityTokens = identityToken.split("\\.");
            String str = new String(Base64Utils.decodeFromString(identityTokens[1]), "UTF-8");
            JSONObject data = JSONObject.parseObject(str);
            String aud = (String) data.get("aud");
            String sub = (String) data.get("sub");
            if (verify(identityToken, aud, sub)) {
                return data;
            }
        } catch (Exception e) {
            log.info("verify(*) error ",e);
        }
        return null;
    }

    /**
     * 验证
     *
     * @param identityToken APP获取的identityToken
     * @param aud           您在您的Apple Developer帐户中的client_id
     * @param sub           用户的唯一标识符对应APP获取到的:user
     * @return true/false
     */
    private static boolean verify(String identityToken, String aud, String sub) {
        try {
            PublicKey publicKey = getPublicKey();
            if (publicKey==null){
                return false;
            }
            JwtParser jwtParser = Jwts.parser().setSigningKey(publicKey);
            jwtParser.requireIssuer("https://appleid.apple.com");
            jwtParser.requireAudience(aud);
            jwtParser.requireSubject(sub);
            Jws<Claims> claim = jwtParser.parseClaimsJws(identityToken);
            if (claim != null && claim.getBody().containsKey("auth_time")) {
                return true;
            }
        } catch (Exception e) {
            log.info("verify(*,*,*) error ", e);
        }
        return false;
    }

    private static PublicKey getPublicKey() {
        try {
            String url = "https://appleid.apple.com/auth/keys";
            RestTemplate restTemplate = new RestTemplate();
            JSONObject data = restTemplate.getForObject(url,JSONObject.class);
            JSONArray jsonArray = data.getJSONArray("keys");
            String n = jsonArray.getJSONObject(0).getString("n");
            String e = jsonArray.getJSONObject(0).getString("e");
            BigInteger modulus = new BigInteger(1, Base64.decodeBase64(n));
            BigInteger publicExponent = new BigInteger(1, Base64.decodeBase64(e));
            RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, publicExponent);
            KeyFactory kf = KeyFactory.getInstance("RSA");
            return kf.generatePublic(spec);
        } catch (Exception e) {
            log.info("getPublicKey error ", e);
        }
        return null;
    }
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飘然生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值