苹果授权登录Sign In With Apple亲测通过版[100%成功]

苹果授权登录Sign In With Apple后台代码实现JAVA版本亲测通过版


废话不多说,直接复制把自己的包名写上就可以用了
有个别的小坑,HttpUtil自己写,没附上
Base64一定要用org.apache.commons.codec.binary.Base64其它的会报错
小提示:苹果的公钥可能是固定的,可以自己实现一个缓存提高授权速度

pom.xml

 <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
</dependency>
package com.;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.haojiao.init.utils.HttpUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import org.apache.commons.codec.binary.Base64;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Base64Utils;

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.RSAPublicKeySpec;
import java.util.HashMap;

public class SignInWithApple {

    private static Logger logger = LoggerFactory.getLogger(SignInWithApple.class);


    @Test
    public void main(){
        verify("1.2.3");
    }

    /**
     * 解密个人信息
     *
     * @param identityToken APP获取的identityToken
     *
     * @return 解密参数:失败返回null  sub就是用户id,用户昵称需要前端传过来
     */
    public static JSONObject verify(String identityToken) {
        try {
            String[] identityTokens = identityToken.split("\\.");
            String token0 = new String(Base64Utils.decodeFromString(identityTokens[0]), "UTF-8");
            String token1 = new String(Base64Utils.decodeFromString(identityTokens[1]), "UTF-8");
            JSONObject data0 = JSONObject.parseObject(token0);
            JSONObject data1 = JSONObject.parseObject(token1);
            String aud = (String) data1.get("aud");
            String sub = (String) data1.get("sub");
            if (verify(data0,identityToken, aud, sub)) {
                return data1;
            }
        } catch (Exception e) {
            logger.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(JSONObject token0,String identityToken, String aud, String sub) {
        try {
            PublicKey publicKey = getPublicKey(token0);
            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) {
            logger.info("verify(*,*,*) error ", e);
        }
        return false;
    }

    private static PublicKey getPublicKey(JSONObject token0) {
        try {
            String str = HttpUtil.get("https://appleid.apple.com/auth/keys", new HashMap<>());
            JSONObject data = JSONObject.parseObject(str);
            JSONArray jsonArray = data.getJSONArray("keys");

            for (int i = 0; i <jsonArray.size() ; i++) {
                JSONObject o = jsonArray.getJSONObject(i);
                String kid = o.getString("kid");
                if (kid.equals(token0.getString("kid"))){
                    String n = o.getString("n");
                    String e = o.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) {
            logger.info("getPublicKey error ", e);
        }
        return null;
    }

}



打个广告,是好人就用微信扫一下,额度大,利息低,按天收~
在这里插入图片描述

请勿转载:来自
CSDN

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值