背景:公司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非法,请重试!”);
}
}
}