苹果登录的后台验证token(JAVA)sign with apple
苹果登录后台token校验分为2种方式:
1、jwt校验
2、授权码校验
我这里记录一下第一种方式
流程大致如下:
添加maven依赖:
<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>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
代码献上:
/** * @Description apple登录--identifyToken校验 * @Author Chongwen.jiang * @Date 2020/2/24 19:28 * @ModifyDate 2020/2/24 19:28 * @Params [identifyToekn] * @Return boolean false:未通过token校验,true:通过校验 */
private boolean checkIdentifyToken(BaseRequest request) {
String identifyToken = request.getIdentifyToken();
logger.info("checkIdentifyToken-identifyToken:{}", identifyToken);
// 向苹果后台获取公钥参数
String appleResp = null;
try {
appleResp = HttpClientCloudUtils.getHttpExecute("https://appleid.apple.com/auth/keys");
logger.info("checkIdentifyToken-appleResp:{}", appleResp);
} catch (Exception e) {
logger.info("checkIdentifyToken-get apple public key fail " + e.getMessage());
throw new PicaException("get apple public key fail Exception", "get apple public key fail");
}
JSONObject appleRespJson = JSONObject.parseObject(appleResp);
String keys = appleRespJson.getString("keys");
JSONArray keysArr = JSONObject.parseArray(keys);
if (identifyToken.split("\\.").length < 2) {
throw new PicaException("get identifyToken fail Exception", "get identifyToken format Exception");
}
JSONObject useAppleAuth = new JSONObject();
String inAuth = new String(Base64.decodeBase64(identifyToken.split("\\.")[0]));
String inKid = JSONObject.parseObject(inAuth).get("kid").toString();
for(Object obj : keysArr){
JSONObject appleAuth = JSONObject.parseObject(obj.toString());
if(inKid.equals(appleAuth.getString("kid"))){
useAppleAuth = appleAuth;
logger.info("checkIdentifyToken-jsonObject1:{}", useAppleAuth);
break;
}
}
// 通过jar生成publicKey
PublicKey publicKey;
try {
Jwk jwa = Jwk.fromValues(useAppleAuth);
publicKey = jwa.getPublicKey();
} catch (Exception e) {
logger.info("checkIdentifyToken-generate publicKey fail " + e.getMessage());
throw new PicaException("checkIdentifyToken-generate publicKey fail", "generate publicKey fail");
}
// 分割前台传过来的identifyToken(jwt格式的token)用base64解码使用
String aud;
String sub;
try {
String claim = new String(Base64.decodeBase64(identifyToken.split("\\.")[1]));
//logger.info("checkIdentifyToken-claim:{}", claim);
aud = JSONObject.parseObject(claim).get("aud").toString();
sub = JSONObject.parseObject(claim).get("sub").toString();
// appleUserId从token中解码取出后赋值
request.setAppleUserId(sub);
} catch (Exception e) {
logger.info("checkIdentifyToken-token decode fail " + e.getMessage());
throw new PicaException("checkIdentifyToken-token decode fail Exception", "token decode fail");
}
return this.verify(publicKey, identifyToken, aud, sub, request);
}
/** * @Description 验证苹果公钥 * @Author Chongwen.jiang * @Date 2020/2/24 19:49 * @ModifyDate 2020/2/24 19:49 * @Params [key, jwt, audience, subject] * @Return boolean */
private boolean verify(PublicKey key, String jwt, String audience, String subject, BaseRequest request) {
JwtParser jwtParser = Jwts.parser().setSigningKey(key);
jwtParser.requireIssuer("https://appleid.apple.com");
jwtParser.requireAudience(audience);
jwtParser.requireSubject(subject);
try {
logger.info("checkIdentifyToken-apple-verify-starting");
Jws<Claims> claim = jwtParser.parseClaimsJws(jwt);
logger.info("acheckIdentifyToken-apple-verify-claim:{}", JSON.toJSONString(claim));
//logger.info("apple-verify-claim.getBody:{}", JSON.toJSONString(claim.getBody()));
if (claim != null && claim.getBody().containsKey("auth_time")) {
request.setInfo(JSON.toJSONString(claim.getBody()));
JSONObject claimBody = JSONObject.parseObject(JSON.toJSONString(claim.getBody()), JSONObject.class);
request.setAppleId(claimBody.getString("email"));
return true;
}
return false;
} catch (ExpiredJwtException e) {
logger.info("checkIdentifyToken-apple token expired " + e.getMessage());
throw new PicaException("apple token expired Exception", "apple token expired");
} catch (Exception e) {
logger.info("checkIdentifyToken-apple token illegal " + e.getMessage());
throw new PicaException("apple token illegal Exception", "apple token illegal");
}
}
参考链接:
jwt技术认识
sign with apple
官方文档
还没有评论,来说两句吧...