zoukankan      html  css  js  c++  java
  • 苹果授权登录

    1.复制工具类

    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import com.auth0.jwk.Jwk;
    import io.jsonwebtoken.*;
    import org.apache.commons.codec.binary.Base64;
    import org.springframework.web.client.RestTemplate;
    
    import java.security.PublicKey;
    
    public class AppleUtil {
    
    
        /**
         * 获取苹果的公钥
         * @return
         * @throws Exception
         */
        private static JSONArray getAuthKeys() throws Exception {
            String url = "https://appleid.apple.com/auth/keys";
            RestTemplate restTemplate = new RestTemplate();
            JSONObject json = restTemplate.getForObject(url,JSONObject.class);
            JSONArray arr = json.getJSONArray("keys");
            return arr;
        }
    
        public static Boolean verify(String jwt) throws  Exception{
            JSONArray arr = getAuthKeys();
            if(arr == null){
                return false;
            }
            JSONObject authKey = null;
    
            //先取苹果第一个key进行校验
            authKey = JSONObject.parseObject(arr.getString(0));
            if(verifyExc(jwt, authKey)){
                return true;
            }else{
                //再取第二个key校验
                authKey = JSONObject.parseObject(arr.getString(1));
                return verifyExc(jwt, authKey);
            }
    
        }
    
        /**
         * 对前端传来的identityToken进行验证
         * @param jwt 对应前端传来的 identityToken
         * @param authKey 苹果的公钥 authKey
         * @return
         * @throws Exception
         */
        public static Boolean verifyExc(String jwt, JSONObject authKey) throws Exception {
    
            Jwk jwa = Jwk.fromValues(authKey);
            PublicKey publicKey = jwa.getPublicKey();
    
            String aud = "";
            String sub = "";
            if (jwt.split("\.").length > 1) {
                String claim = new String(Base64.decodeBase64(jwt.split("\.")[1]));
                aud = JSONObject.parseObject(claim).get("aud").toString();
                sub = JSONObject.parseObject(claim).get("sub").toString();
            }
            JwtParser jwtParser = Jwts.parser().setSigningKey(publicKey);
            jwtParser.requireIssuer("https://appleid.apple.com");
            jwtParser.requireAudience(aud);
            jwtParser.requireSubject(sub);
    
            try {
                Jws<Claims> claim = jwtParser.parseClaimsJws(jwt);
                if (claim != null && claim.getBody().containsKey("auth_time")) {
                    System.out.println(claim);
                    return true;
                }
                return false;
            } catch (ExpiredJwtException e) {
                return false;
            } catch (Exception e) {
                return false;
            }
        }
    
    
    
        /**
         * 对前端传来的JWT字符串identityToken的第二部分进行解码
         * 主要获取其中的aud和sub,aud大概对应ios前端的包名,sub大概对应当前用户的授权的openID
         * @param identityToken
         * @return  {"aud":"com.xkj.****","sub":"000***.8da764d3f9e34d2183e8da08a1057***.0***","c_hash":"UsKAuEoI-****","email_verified":"true","auth_time":1574673481,"iss":"https://appleid.apple.com","exp":1574674081,"iat":1574673481,"email":"****@qq.com"}
         */
        public static JSONObject parserIdentityToken(String identityToken){
            String[] arr = identityToken.split("\.");
            Base64 base64 = new Base64();
            String decode = new String (base64.decodeBase64(arr[1]));
            String substring = decode.substring(0, decode.indexOf("}")+1);
            JSONObject jsonObject = JSON.parseObject(substring);
            return  jsonObject;
        }
    
    }

    2.编写业务逻辑代码

        public AuthUser appleLogin(String identityToken){
            String randomStr = UUID.randomUUID().toString();
            try {
                //验证identityToken
                if(!AppleUtil.verify(identityToken)){
                    throw new RuntimeException("identityToken验证失败");
                }
                //对identityToken解码
                JSONObject json = AppleUtil.parserIdentityToken(identityToken);
                if(json == null){
                    throw new RuntimeException("identityToken解码失败");
                }
                //苹果用户唯一标识
                String appleId = new MD5().digestHex16(json.get("sub").toString()) ;
                SysUser user = baseMapper.selectOne(new MpUtil<SysUser>().queryNormal().eq(SysUser.APPLE_ID,appleId));
                //判断该账户是否被禁用
                if(user!=null && user.getDataActive().equals(StatusEnum.STATUS_DISABLE.getStrCode())){
                    throw new RuntimeException("该账户已被禁用,请联系管理员!");
                }
                //授权绑定过直接获取token
                if(user!=null){
                     //非密码登录设置密码为空
                     user.setPassword(null);
                     return getToken(user);
                 //把苹果的登录唯一标识存储redis中
                }else {
                    RedisUtil.addDataSecond(StrUtil.format(APPLE_AUTH_LOGIN, randomStr),appleId,600l);
                    AuthUser authUser = new AuthUser();
                    //把键存入这个字段
                    authUser.setAccessToken(randomStr);
                    return authUser;
    
                }
            }catch (Exception e){
                throw new RuntimeException("系统错误!请联系管理员");
            }
        }
  • 相关阅读:
    Linux脚本中使用特定JDK
    redis 模糊匹配批量清理 keys
    git push 本地项目推送到远程分支
    extentreports报告插件之extentX之服务搭建(三)
    extentreports报告插件与testng集成(二)
    extentreports报告插件与testng集成(一)
    初识ios自动化(一)
    css 选择器
    appium移动端测试之滑动(二)
    使用appium进行ios测试,启动inspector时遇到的问题(一)
  • 原文地址:https://www.cnblogs.com/huqi96/p/14214598.html
Copyright © 2011-2022 走看看