Sign in with Apple(苹果授权登陆)服务端验证-测试通过版

Sign in with Apple(苹果授权登陆)服务端验证-测试通过版

苹果登录方式有2种,这里介绍基于JWT算法验证
废话不多说,上代码

1.先引用2个jwt用到的jar包
        <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>
2.算法的工具类
package com.imc.common;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwk.Jwk;
import io.jsonwebtoken.*;
import org.apache.commons.codec.binary.Base64;

import java.security.PublicKey;
import java.util.HashMap;

/**
 * <br>
 * date:2012/03/26 9:43
 *
 * @author xh
 * @version 1.0
 * @since JDK 1.8
 */
public class SignInWithAppleHelper {

    /**
     * 解密个人信息
     *
     * @param identityToken APP获取的identityToken
     * @return 解密参数:失败返回null
     */
    public String verify(String identityToken) {
        try {
            if (identityToken.split("\\.").length > 1) {
                String claim = new String(Base64.decodeBase64(identityToken.split("\\.")[1]));
                String aud = JSONObject.parseObject(claim).get("aud").toString();
                String sub = JSONObject.parseObject(claim).get("sub").toString();
                String reuslt = this.verify(this.getPublicKey(), identityToken, aud, sub);
                if (reuslt.equals("SUCCESS")) {
                    System.out.println("苹果登录成功");
                    return claim;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String verify(PublicKey key, String jwt, String audience, String subject) throws Exception {
        String result = "FAIL";
        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")) {
                result = "SUCCESS";
                return result;
            }
        } catch (ExpiredJwtException e) {
            throw new Exception("苹果token过期", e);
        } catch (SignatureException e) {
            throw new Exception("苹果token非法", e);
        }
        return result;
    }

    /**
     * 从hex string生成公钥
     *
     * @return 构造好的公钥
     */
    public PublicKey getPublicKey() {
        try {
            String str = HttpHelper.get("https://appleid.apple.com/auth/keys", new HashMap<String, String>());
            JSONObject data = JSONObject.parseObject(str);
            String keys = data.getString("keys");
            JSONArray arr = JSONObject.parseArray(keys);
            JSONObject jsonObject1 = JSONObject.parseObject(arr.getString(0));
            Jwk jwa = Jwk.fromValues(jsonObject1);
            PublicKey publicKey = jwa.getPublicKey();
            return publicKey;
        } catch (final Exception e) {
            e.printStackTrace();
        }
        return null;
    }


}


三方登录调用验证工具类

仔细看,很多文档都没有的东西来了,我这块用到了缓存,为什么用缓存呢,因为这块代码在我反复测试的情况下,移动端给的identityToken参数你频繁操作的话jwt验证会报错,在本楼主大量实验的情况下测试出 一个userID 对应的identityToken有效期是10分钟,userID是苹果给用户的唯一标识,所以我把userID当做key ,把identityToken存到redis内,我这里缓存是9分钟,我是考虑到网络IO等,反正不差那1分钟,经测试没问题,产品逻辑可适当修改

 if (type == Constants.LOGIN_TYPE_APPLE) {
            //苹果登陆使用参数
            String identityToken = params.getString("identityToken");
            //苹果登录唯一表示
            thirdLoginId = params.getString("userID");
            if (redisCacheUtil.get(thirdLoginId) != null) {
                identityToken = redisCacheUtil.get(thirdLoginId) + "";
            }
            //这里可以根据thirdLoginId查询数据库是否存在,如果存在就返回用户信息
            //苹果登陆验证
            SignInWithAppleHelper signInWithAppleHelper = new SignInWithAppleHelper();
            String data = signInWithAppleHelper.verify(identityToken);
            if (data != null) {
                //苹果登录唯一表示
                thirdLoginId = JSONObject.parseObject(data).get("sub").toString();
                if (redisCacheUtil.get(thirdLoginId) == null) {
                    redisCacheUtil.set(thirdLoginId, identityToken, 540);
                }
            } else {
                throw new CustomException(code_3010, "与苹果服务器链接超时,请重新尝试。");
            }
        }

不喜勿喷,感谢各位大大的阅读🥰

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Unity3D是一款流行的跨平台游戏开发引擎,支持多种移动平台和操作系统。最近,苹果推出了“Sign in with Apple”功能,该功能允许用户使用其Apple ID来登录第三方应用程序。 要在Unity3D中接入Sign in with Apple”功能,需要遵循以下步骤: 1. 首先,确保你的Unity3D本是最新的,以便能够支持最新的API和功能。 2. 在苹果开发者平台上创建一个新的App ID,并将其与你的Unity3D项目关联。确保在App ID设置中启用“Sign in with Apple”功能。 3. 在Unity3D中,编写代码以实现与苹果登录服务通信的逻辑。你需要使用Unity内置的网络API,通过发送HTTP请求和接收回复来实现与苹果服务器的通信。 4. 在Unity3D项目中创建一个用户界面,允许用户点击“Sign in with Apple”按钮。当用户点击这个按钮时,你的代码将向苹果服务器发送请求,获取用户的验证凭证。 5. 将从苹果服务器接收到的验证凭证与你的后端服务器通信。你的后端服务器需要验证这个凭证的有效性,并通过向苹果服务器发送请求获得用户的基本信息。 6. 在Unity3D中使用这些用户信息,例如显示用户的用户名、头像等。 需要注意的是,为了保护用户的隐私,苹果有一些要求和限制,开发人员需要遵守这些规定,例如要求提供“其他登录选项”以及对于用户与苹果登录服务的数据处理等。 总结:要在Unity3D中接入Sign in with Apple”功能,你需要使用最新本的Unity3D、遵循苹果开发者平台的规定、实现与苹果服务器的通信逻辑、创建用户界面、验证凭证、获取用户信息,并遵守苹果的隐私规定。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值