IOS苹果账号三方登录服务器端验证

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 20:37   3425   0

背景:公司app项目有一个苹果账号三方登录功能,其中需要后台提供苹果验证。按照网上搜到的方法,有时候会匹配不成功,将ios请求的内容存到redis里面,redis设置4分钟过期。

下面是代码,直接复制过去应该要修改的,先看懂啥意思自己在修改吧。里面的参数jwt是app端传来的。里面的从redis存取的方法应该不能直接用,写成你自己的方法,也可以直接去掉,去掉有可能会验证不通过。我个人觉得应该是后台请求的信息和app反过来的信息时间上有可能不同步,就会验证不通过,所以通过redis保存一下4分钟。据说是这个token5分钟过期。

package com.jeecg.wechat.controlle;
import java.security.PublicKey;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.net.util.Base64;
import org.jeecgframework.core.common.service.impl.RedisService;
import org.jeecgframework.core.util.HttpRequest;
import org.jeecgframework.core.util.oConvertUtils;
import org.jeecgframework.jwt.util.ResponseMessage;
import org.jeecgframework.jwt.util.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwk.InvalidPublicKeyException;
import com.auth0.jwk.Jwk;
import com.jeecg.share.util.RedisConfig;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;

/**ios  appleid三方登录后台验证方法
 * 参考:https://blog.csdn.net/wth905541529/article/details/103312174
 * @author Administrator
 *
 */
@Controller
@RequestMapping("/IosController")
public class IosController {
 private static final Logger log = LoggerFactory.getLogger(IosController.class);
 @Autowired
 private RedisService redisService;
 /**
  * 第一步:手机端操作获取code
  * 第二步:通过code获取access_token(在自己服务器端做)
  * @return
  */
 @RequestMapping(value = "/appleAuth",method = RequestMethod.GET)
 @ResponseBody
 public Object appleAuth(String jwt) {
  //从redis里面取jwt
  if (jwt.split("\\.").length > 1) {
            String claim = new String(Base64.decodeBase64(jwt.split("\\.")[1]));
            String aud = JSONObject.parseObject(claim).get("aud").toString();
            String sub = JSONObject.parseObject(claim).get("sub").toString();    //用户openid
            if (oConvertUtils.isNotEmpty(redisService.get(sub))) {
             jwt = redisService.get(sub) + "";
            }
        }
  
  
  JSONObject jsonObject = null;
  jsonObject = HttpRequest.sendGet("https://appleid.apple.com/auth/keys", "");
  if(oConvertUtils.isEmpty(jsonObject)){
   return Result.error("网络故障,请重试!");// 未获取到公钥
  }
        String keys = jsonObject.getString("keys");
        JSONArray arr = JSONObject.parseArray(keys);
        JSONObject jsonObject1 = JSONObject.parseObject(arr.getString(0));
        Jwk jwa = Jwk.fromValues(jsonObject1);
        try {
            // 生成苹果公钥
            PublicKey publicKey = jwa.getPublicKey();
//            String hearder = new String(Base64.decodeBase64(jwt.split("\\.")[0]));
            if (jwt.split("\\.").length > 1) {
                String claim = new String(Base64.decodeBase64(jwt.split("\\.")[1]));
                String aud = JSONObject.parseObject(claim).get("aud").toString();
                String sub = JSONObject.parseObject(claim).get("sub").toString();
                return verify(publicKey, jwt, aud, sub);
            }
            //return "FAIL";
            return Result.error("FAIL");
        } catch (InvalidPublicKeyException e) {
           // throw new Exception("转换苹果公钥失败", e);
         return Result.error("转换苹果公钥失败,请重试!");
        }
    }

 /**
  * 验证苹果公钥
  * @param key
  * @param jwt
  * @param audience
  * @param subject
  * @return
  */
 public Object verify(PublicKey key, String jwt, String audience, String subject) {
     JwtParser jwtParser = Jwts.parser().setSigningKey(key);
     jwtParser.requireIssuer("https://appleid.apple.com");
     jwtParser.requireAudience(audience);
     jwtParser.requireSubject(subject);
     try {
         Jws<Claims> claim = jwtParser.parseClaimsJws(jwt);
         if (claim != null && claim.getBody().containsKey("auth_time")) {
          //System.out.println("【成功:】  【key】:"+key+" 【jwt】:"+jwt+" 【audience】:"+audience+" 【subject】:"+subject+" 【claim】:"+claim);
                 if (redisService.get(subject) == null) {
                  redisService.set(subject, jwt);
                 }
          
          return Result.success();
         }
         return Result.error("FAIL");
     } catch (ExpiredJwtException e) {
        //throw new SysException("苹果token过期", e);
      redisService.delete(subject);
       e.printStackTrace();  
       return Result.error("苹果token过期,请重试!");
     } catch (Exception e) {
      
         //throw new SysException("苹果token非法", e);
       e.printStackTrace();  
      //System.out.println("【失败:】  【key】:"+key+" 【jwt】:"+jwt+" 【audience】:"+audience+" 【subject】:"+subject+" 【claim】:");
       return Result.error("苹果token非法,请重试!");
     }
 }
}

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP