蘋果登錄的後臺驗證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
官方文檔
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章