收藏
回答

设置小程序隐私 48001 api unauthorized

第三方平台小程序开发遇到问题,当第三方平台调用商家授权小程序时,可以正常返回 :

这里:授权小程序APPID及平台APPID

{"authorizer_appid": "wx6a79d9e20634b4fb",  componet_appid: "wxc24950555e542854"}

授权商家小程序ID: wx6a79d9e20634b4fb (这个小程序是通过快速创建企业小程序接口创建的,商家也已授权)
  
调用小程序详情接口:https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=" + component_access_token;

返回如下: API权限集ID:18 已经拿到。



{
  "authorizer_info": {
    "nick_name": "",
    "service_type_info": {
      "id": 0
    },
    "verify_type_info": {
      "id": 0
    },
    "user_name": "gh_61f6bc98c7a7",
    "alias": "",
    "qrcode_url": "http://mmbiz.qpic.cn/mmbiz_jpg/GAUFLLdxPuNsnVPvMkZSzGWu8QGpHdkpJkFnvnl9TJzYibLic4bBM0dTJxPNWwdnPmRxnH4InG3JgUDvU0yfrTag/0",
    "business_info": {
      "open_pay": 1,
      "open_shake": 0,
      "open_scan": 0,
      "open_card": 0,
      "open_store": 0
    },
    "idc": 1,
    "principal_name": "佛山市花梵花艺设计有限公司",
    "signature": "",
    "MiniProgramInfo": {
      "network": {
        "RequestDomain": [],
        "WsRequestDomain": [],
        "UploadDomain": [],
        "DownloadDomain": [],
        "BizDomain": [],
        "UDPDomain": [],
        "TCPDomain": [],
        "PrefetchDNSDomain": [],
        "NewRequestDomain": [],
        "NewWsRequestDomain": [],
        "NewUploadDomain": [],
        "NewDownloadDomain": [],
        "NewBizDomain": [],
        "NewUDPDomain": [],
        "NewTCPDomain": [],
        "NewPrefetchDNSDomain": []
      },
      "categories": [],
      "visit_status": 0
    },
    "register_type": 6,
    "account_status": 1,
    "basic_config": {
      "is_phone_configured": false,
      "is_email_configured": false
    }
  },
  "authorization_info": {
    "authorizer_appid": "wx6a79d9e20634b4fb",
    "authorizer_refresh_token": "refreshtoken@@@DUewg9oNgD22AYF8hgS1Tv5UF4uVnpWHVkEeXjXsM-0",
    "func_info": [
      {
        "funcscope_category": {
          "id": 17
        }
      },
      {
        "funcscope_category": {
          "id": 18
        },
        "confirm_info": {
          "need_confirm": 0,
          "already_confirm": 0,
          "can_confirm": 0
        }
      },
      {
        "funcscope_category": {
          "id": 19
        }
      },
      {
        "funcscope_category": {
          "id": 25
        },
        "confirm_info": {
          "need_confirm": 0,
          "already_confirm": 0,
          "can_confirm": 0
        }
      },
      {
        "funcscope_category": {
          "id": 30
        },
        "confirm_info": {
          "need_confirm": 0,
          "already_confirm": 0,
          "can_confirm": 0
        }
      },
      {
        "funcscope_category": {
          "id": 31
        },
        "confirm_info": {
          "need_confirm": 0,
          "already_confirm": 0,
          "can_confirm": 0
        }
      },
      {
        "funcscope_category": {
          "id": 36
        }
      },
      {
        "funcscope_category": {
          "id": 37
        }
      },
      {
        "funcscope_category": {
          "id": 40
        }
      },
      {
        "funcscope_category": {
          "id": 41
        },
        "confirm_info": {
          "need_confirm": 0,
          "already_confirm": 0,
          "can_confirm": 0
        }
      },
      {
        "funcscope_category": {
          "id": 45
        },
        "confirm_info": {
          "need_confirm": 0,
          "already_confirm": 0,
          "can_confirm": 0
        }
      },
      {
        "funcscope_category": {
          "id": 48
        }
      },
      {
        "funcscope_category": {
          "id": 49
        },
        "confirm_info": {
          "need_confirm": 0,
          "already_confirm": 0,
          "can_confirm": 0
        }
      },
      {
        "funcscope_category": {
          "id": 51
        }
      },
      {
        "funcscope_category": {
          "id": 52
        }
      },
      {
        "funcscope_category": {
          "id": 57
        }
      },
      {
        "funcscope_category": {
          "id": 65
        }
      },
      {
        "funcscope_category": {
          "id": 67
        }
      },
      {
        "funcscope_category": {
          "id": 70
        }
      },
      {
        "funcscope_category": {
          "id": 71
        },
        "confirm_info": {
          "need_confirm": 0,
          "already_confirm": 0,
          "can_confirm": 0
        }
      },
      {
        "funcscope_category": {
          "id": 73
        },
        "confirm_info": {
          "need_confirm": 0,
          "already_confirm": 0,
          "can_confirm": 0
        }
      },
      {
        "funcscope_category": {
          "id": 76
        },
        "confirm_info": {
          "need_confirm": 0,
          "already_confirm": 0,
          "can_confirm": 0
        }
      },
      {
        "funcscope_category": {
          "id": 81
        },
        "confirm_info": {
          "need_confirm": 0,
          "already_confirm": 0,
          "can_confirm": 0
        }
      },
      {
        "funcscope_category": {
          "id": 84
        }
      },
      {
        "funcscope_category": {
          "id": 85
        }
      },
      {
        "funcscope_category": {
          "id": 86
        }
      },
      {
        "funcscope_category": {
          "id": 88
        }
      },
      {
        "funcscope_category": {
          "id": 93
        }
      },
      {
        "funcscope_category": {
          "id": 99
        }
      },
      {
        "funcscope_category": {
          "id": 102
        }
      },
      {
        "funcscope_category": {
          "id": 104
        }
      },
      {
        "funcscope_category": {
          "id": 105
        }
      },
      {
        "funcscope_category": {
          "id": 112
        }
      }
    ]
  }
}




接着,调用: https://api.weixin.qq.com/wxa/gettemplatedraftlist?access_token= 商家授权的appid ( authorizer_appid )

返回: 48001 api unauthorized

请帮我定位一下问题,谢谢!

微信: 13926003676


回答关注问题邀请回答
收藏

1 个回答

  • 鹏哥
    鹏哥
    2023-02-03

    已经解决。 代商家获取小程序详情接口,在这分享一下:

    @RequestMapping(value = {"/qurey/minin/info"}, method = RequestMethod.POST)
    public JSONObject queryMiniNameStatus(@RequestBody JSONObject body) {
    
        try {
    
            return wechatPlatformService.queryMiniInfo(body);
    
        } catch (Exception e) {
            log.error(StackTool.error(e, 100));
            return new JSONObject().fluentPut("resCode", Constants.KEY_OP_FAIL).fluentPut("resMsg", e.getMessage());
        }
    
    
    }
    
    /**
     * 查询小程序名称设置状态
     *
     * @param body
     * @return
     * @throws Exception
     *
     
     */
    public JSONObject queryMiniInfo(JSONObject body) throws Exception {
    
        String component_appid = body.getString("component_appid");
    
        String authorizer_appid = body.getString("authorizer_appid");
    
        PlatformGrant grant = getApiToken(component_appid, authorizer_appid);
    
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=utf-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_XML.toString());
    
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        String url = "https://api.weixin.qq.com/cgi-bin/account/getaccountbasicinfo?access_token=" + grant.getAuthorizer_access_token();
        body.remove("component_appid");
        body.remove("authorizer_appid");
    
        HttpEntity<JSONObject> formEntity = new HttpEntity<JSONObject>(body, headers);
        JSONObject res = restTemplate.postForObject(url, formEntity, JSONObject.class);
        log.info("---->小程序基本信息查询 res {}", res);
        Integer status = res.getInteger("errcode");
    
        JSONObject  head_image_info = res.getJSONObject("head_image_info");
        if (head_image_info != null) {
    
           String head_image_url = head_image_info.getString("head_image_url");
    
            if ( StringUtils.isEmpty(grant.getHead_image_url()) ) {
    
                grant.setHead_image_url(head_image_url);
    
                platformGrantRepository.save(grant);
                log.info("--->更新小程序的图像<---- {}",head_image_url);
            }
    
        }
    
    
        JSONObject result = new JSONObject();
        if (status != null && status.intValue() == 0) {
            result.put("resCode", "0");
            result.put("resMsg", "OK");
            result.put("result", res);
    
    
        } else {
            result.put("resCode", Constants.KEY_OP_FAIL);
            result.put("resMsg", res.getString("errmsg"));
    
        }
        return result;
    
    
    }
    
    


    其中,获取第三方授权的 access_token 放在缓存中,过期了才向微信获取,并且持久化到表 PlatformGrant 中。以下是源码参照:


    /**
     * 获取/刷新接口调用令牌
     * @param component_appid: 第三方平台appid
     * @param grant:
     * @return
     */
    
    public PlatformGrant getApiToken(String component_appid, String authorizer_appid) throws Exception {
    
        String component_access_token =  getComponentAccessToken(component_appid);
        PlatformGrant grant = getPlarformGrant(component_appid,authorizer_appid) ;
        if (grant == null)  {
    
            throw new RuntimeException("平台未保存用户的授权信息");
        }
    
        // 先不着急重新调用接口获取
        if ( grant.getExpires_in() != null && grant.getUpdate_time() != null) {
            if (DateUtil.valid(grant.getUpdate_time(), grant.getExpires_in())){
    
                // 没有过期
                return grant;
    
            }
        }
    
    
    
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=utf-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        JSONObject reqBody = new JSONObject();
        reqBody.put("component_access_token", component_access_token);
        reqBody.put("component_appid", component_appid);
        reqBody.put("authorizer_appid", authorizer_appid);
        reqBody.put("authorizer_refresh_token", grant.getAuthorizer_refresh_token());
    
        HttpEntity<JSONObject> formEntity = new HttpEntity<JSONObject>(reqBody, headers);
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        String url = "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token="+component_access_token;
        JSONObject   json  = restTemplate.postForObject(url, formEntity, JSONObject.class);
        log.info(">>>授权码获取授权信息 返回:{}",json);
        if ( json.getIntValue("errcode") != 0 )  {
    
            // {"errcode":61023,"errmsg":"refresh_token is invalid rid: 6228c03e-19027c0c-7a98021d"}
            if (json.getString("errmsg").indexOf("refresh_token is invalid") != -1) { //需要从数据库取
    
            }
        }
    
        String authorizer_access_token = json.getString("authorizer_access_token");
        String authorizer_refresh_token = json.getString("authorizer_refresh_token");
        int expires_in = json.getIntValue("expires_in");
    
        grant = new  PlatformGrant();
        grant.setComponent_appid(component_appid);
        grant.setAuthorizer_access_token(authorizer_access_token);
        grant.setAuthorizer_appid(authorizer_appid);
        grant.setAuthorizer_refresh_token(authorizer_refresh_token);
        grant.setExpires_in(expires_in);
        return savePlatformGrant(grant);
    
    
    
    }
    


    先从缓存中获取商家授权acess_token,获取不到或过期了再实时查询

    /**
     * 获取平台 component_access_token 有效期2h
     * @return
     */
    public String getComponentAccessToken(String appId)  {
    
    
        WechatToken token = null;
        String key= RedisTool.getComponentAccessTokenKey(appId);
        //先从缓存中取:
        try {
    
            token =( WechatToken)redisTemplate.opsForValue().get(key);
            if( null !=  token) {
    
                log.info("---成功获取ComponetAccessToken:{}",token.toString());
    
                return token.getToken();
            }
    
    
        }catch(Exception e) {
            log.warn("----->getComponentAccessToken异常<-----");
            log.error(StackTool.error(e,100));
    
        }
    
    
        log.info("--缓存中未获取到ComponetAccessToken 即时查询接口 ----" );
        String url = "https://api.weixin.qq.com/cgi-bin/component/api_component_token";
        JSONObject reqBody = new JSONObject();
        String appSecret = null;
    
        if (appId.equals(wXBizMsgCrypt.getAppId())) {
    
            appSecret = wXBizMsgCrypt.getAppSecret();
        }else{
            MuchApiWechat api = muchApiWechatRepository.findMuchApiWechat(appId);
            if (api == null) {
                throw new RuntimeException("平台没有配置第三方小程序"); // wxc24950555e542854
            }
            appSecret = api.getAppsecret();
    
        }
        reqBody.put("component_appid", appId);
        reqBody.put("component_appsecret", appSecret);
    
        String component_verify_ticket = getComponentVerifyTicket(appId);
    
        if (StringUtils.isEmpty(component_verify_ticket)) {
    
            throw new RuntimeException("component_verify_ticket为空,请联系平台技术人员");
    
        }
        reqBody.put("component_verify_ticket", component_verify_ticket);
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=utf-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_XML.toString());
        HttpEntity<JSONObject> formEntity = new HttpEntity<JSONObject>(reqBody, headers);
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        JSONObject result = restTemplate.postForObject(url, formEntity, JSONObject.class);
        log.info(">>>获取令牌返回: result="+result);
    
        //  result={"errcode":61004,"errmsg":"access clientip is not registered requestIP: XX rid: 63a0f0bf-21116836-466eea46"}
        Integer errcode = result.getInteger("errcode") ;
    
        if (errcode != null && errcode.intValue() != 0) {
    
                 throw new RuntimeException(result.getString("errmsg"));
        }
    
        String component_access_token = result.getString("component_access_token");
    
        if (!StringUtils.isEmpty(component_access_token)) {
            Long now=System.currentTimeMillis()/1000;
            token  = new WechatToken(now,component_access_token );
            try{
                redisTemplate.opsForValue().set(key, token , 7200, TimeUnit.SECONDS);
            }catch(Exception e){
                log.warn("redis component_access_token 异常");
            }
        }
    
        log.info("---->第三方平台 access_token:{}", component_access_token);
    
        return component_access_token;
    
    }
    
    



    最后, 通过第三方平台来管理商家微信小程序,也可以由商家来自助管理。如:设置小程序图像、小程序介绍等信息。贴一张图片大家看看效果。微信的接口调用正确了还是非常稳定的。 之所以调用出错是没有使用商家的授权 authorizer_access_token

    2023-02-03
    有用 1
    回复
登录 后发表内容