欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

IOS APPID一键登录服务端验证

程序员文章站 2022-03-03 10:14:47
...
public class IosAppIdLoginServiceImp {

    private static final Logger LOGGER = LoggerFactory.getLogger(IosAppIdLoginServiceImpl.class);
@Autowired
private PropertiesResouseUtil propertiesResouseUtil;
    private static final String AUTH_TIME = "auth_time";
    private final static int READ_TIMEOUT = 100;
    private final static int CONNECT_TIMEOUT = 60;
@Override
public Response<T> verifyIdentityToken(Request<IosAppIdLoginDto> request) {
        Response<T> response = new Response<>();
IosAppIdLoginDto iosAppIdLoginDto = request.getRequestParam();
response.setResult(iosAppIdLoginDto);
        try {
            //解析
Map<String, JSONObject> json = parserIdentityToken(iosAppIdLoginDto.getIdentityToken());
JSONObject header = json.get("header");
String kid = header.getString("kid");
//生成publickey
PublicKey publicKey = getPublicKey(kid);
            if (publicKey == null) {
                iosAppIdLoginDto.setSuccess(false);
LOGGER.info("获取苹果验证公钥失败:kid={}",kid);
                return commonResponse;
}
            JSONObject payload = json.get("payload");
//验证
JwtParser jwtParser = Jwts.parser().setSigningKey(publicKey);
jwtParser.requireIssuer(propertiesResouseUtil.getProperty("apple.url"));//+"/auth/keys"
jwtParser.requireAudience(payload.getString("aud"));
jwtParser.requireSubject(payload.getString("sub"));
Jws<Claims> claim = jwtParser.parseClaimsJws(iosAppIdLoginDto.getIdentityToken());
            if (claim != null && claim.getBody().containsKey(AUTH_TIME)) {
//                String sub = claim.getBody().get("sub").toString();//用户的Apple的openId
//                String iss = claim.getBody().get("iss").toString();
//                String aud = claim.getBody().get("aud").toString();
iosAppIdLoginDto.setSuccess(true);
}
        } catch (ExpiredJwtException e1) {
            iosAppIdLoginDto.setSuccess(false);
LOGGER.error("apple token verify fail,identityToken is expired!",e1);
} catch (Exception e2) {
            iosAppIdLoginDto.setSuccess(false);
LOGGER.error("apple token verify fail,error={}", e2);
}

        return commonResponse;
}

    /**
     * 对前端传来的JWT字符串identityToken的第二部分进行解码
     * 主要获取其中的aud和sub,aud对应ios前端的包名,sub对应当前用户的授权openID
     *
     * @param identityToken
* @return
*/
private Map<String, JSONObject> parserIdentityToken(String identityToken) {
        Map<String, JSONObject> map = new HashMap<String, JSONObject>();
String[] arr = identityToken.split("\\.");
String deHeader = new String(Base64.decodeBase64(arr[0]));
JSONObject header = JSON.parseObject(deHeader);
LOGGER.info("获取的header={}",header);
map.put("header", header);
String dePayload = new String(Base64.decodeBase64(arr[1]));
LOGGER.info("获取dePayload={}",header);
JSONObject payload = JSON.parseObject(dePayload);
map.put("payload", payload);
        return map;
}

    /**
     * 获取publickey
     * @param kid
* @return
*/
private PublicKey getPublicKey(String kid) {
         LOGGER.info("get apple public key start,kid={}", kid);
        try {

            Proxy proxy = new Proxy(Proxy.Type.HTTP,new InetSocketAddress(propertiesResouseUtil.getProperty("httpproxy.url"),
Integer.parseInt(propertiesResouseUtil.getProperty("httpproxy.port"))));
OkHttpClient client = new OkHttpClient().newBuilder().proxy(proxy).connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS).readTimeout(READ_TIMEOUT, TimeUnit.SECONDS).build();
Request request = new Request.Builder().url(propertiesResouseUtil.getProperty("apple.url")+"/auth/keys").build();
Response response = client.newCall(request).execute();
            if(response.isSuccessful()){
                // 得到响应体中的身体,将其转成  string
String string = response.body().string();
JSONObject data = JSONObject.parseObject(string);
JSONArray jsonArray = data.getJSONArray("keys");
                if(jsonArray.isEmpty()) {
                    return null;
}
                for (Object object : jsonArray) {
                    JSONObject json = ((JSONObject)object);
                    if(json.getString("kid").equals(kid)) {
                        json = ((JSONObject)object);
Jwk jwa = Jwk.fromValues(json);
                        return jwa.getPublicKey();
}
                }

            }
        } catch (final Exception e) {
            LOGGER.error("apple getPublicKey error", e);
}

        return null;
}


}

pom.xml 引用包

<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>

 

相关标签: apple