蘋果登錄後臺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
官方文檔