苹果登录的后台验证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
官方文档
在这里插入图片描述

原创文章 55 获赞 6 访问量 22万+

猜你喜欢

转载自blog.csdn.net/weixin_41205148/article/details/104608727