企微获取access_token、jsapi_ticket、JS-SDK-signature

本篇主要叙述Java对接企微必要信息等,后续接口根据各接口需求来获取企微必要信息(access_token、jsapi_ticket等),此处附上企微开发接口文档

获取企微access_token

获取access_token是调用企业微信API接口的第一步,相当于创建了一个登录凭证,其它的业务API接口,都需要依赖于access_token来鉴权调用者身份。

请求参数:

参数

必须

说明

corpid

企业ID

corpsecret

应用的凭证密钥,注意应用需要是启用状态

企业ID:每个企业都拥有唯一的corpid,获取此信息可在管理后台“我的企业”-“企业信息”下查看“企业ID”(需要有管理员权限)

凭证秘钥:在管理后台->“应用管理”->“应用”->“自建”,点进某个应用,即可看到。

返回结果:

参数

说明

errcode

出错返回码,为0表示成功,非0表示调用失败

errmsg

返回码提示语

access_token

获取到的凭证,最长为512字节

expires_in

凭证的有效时间(秒)

注意事项:对于access_token的获取官方规定不能频繁调用gettoken接口,否则会受到频率拦截,所以一般选择缓存,此文选择用Redis进行缓存。access_token的有效期正常情况下为7200秒(2小时)。

Java中获取access_token的代码实例如下
 

public String getAccessToken() {
    //从缓存中获取access_token
    String weComAccessToken = (String) redisTemplate.opsForValue().get(WECOM_ACCESS_TOKEN);
    if (!StringUtils.isEmpty(weComAccessToken)) {
        return weComAccessToken;
    }
    try {
        //这里的企业id和企业秘钥是在配置文件中获取,此处修改看个人。
        String corpid = weComProperties.getClientId();
        String corpsecret = weComProperties.getClientSecret();
        String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + clientId + "&corpsecret=" + clientSecret;
        String resultStr = HttpUtil.get(url);
        
        JSONObject result = JSONObject.parseObject(resultStr);
        //非空判断
        if (result == null) {
            throw exception(DATA_NOT_EXIST);
        }
        String accessToken = result.getString("access_token");
        String expiresIn = result.getString("expires_in");
        //存入redis
        redisTemplate.opsForValue().set(WECOM_ACCESS_TOKEN, accessToken,Long.valueOf(expiresIn), TimeUnit.SECONDS);
        return result.getString("access_token");
    } catch (ServiceException e) {
        throw new RuntimeException(e);
    }
}

获取企业jsapi_ticket

jsapi_ticket是H5应用调用企业微信JS接口的临时票据,获取企微的jsapi_ticket与获取access_token过程大致相同。

请求参数:

参数

必须

说明

access_token

调用接口凭证

返回参数:

参数

说明

errcode

出错返回码,为0表示成功,非0表示调用失败

errmsg

返回码提示语

ticket

生成签名所需的jsapi_ticket,最长为512字节

expires_in

凭证的有效时间(秒)

注意事项:此处获取次数官方也有做次数限制(一小时内,一个企业最多可获取400次,且单个应用不能超过100次,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务),故需要做缓存处理,此处做的也是缓存也是存入Redis中。正常情况下,jsapi_ticket的有效期为7200秒。

Java中获取jsapi_ticket的代码实例如下

public String getJsapiTicket() {
    //缓存中获取数据
    String jsapiTicket = (String) redisTemplate.opsForValue().get(WECOM_JSAPI_TICKET);
    if (!StringUtils.isEmpty(jsapiTicket)) {
        return jsapiTicket;
    }
    try {
        String accessToken = getAccessToken();
        String url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=" + accessToken+"&type=agent_config";
        String resultStr = HttpUtil.get(url);
        JSONObject result = JSONObject.parseObject(resultStr);
        if (result == null) {
            throw exception(DATA_NOT_EXIST);
        }
        String ticket = result.getString("ticket");
        String expiresIn = result.getString("expires_in");
        //存入redis
        redisTemplate.opsForValue().set(WECOM_JSAPI_TICKET, ticket,Long.valueOf(expiresIn), TimeUnit.SECONDS);
        return result.getString("ticket");
    } catch (ServiceException e) {
        throw new RuntimeException(e);
    }
}

JS-SDK相关参数

前端在处理企微JS-SDK需要通过config接口注入权限验证配置,那配置中的一些参数则后端做处理后传给前端,所以此处做的是将相关参数传给前端。

wx.config({
  beta: true,// 必须这么写,否则wx.invoke调用形式的jsapi会有问题
  debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  appId: '', // 必填,企业微信的corpID,必须是本企业的corpID,不允许跨企业使用
  timestamp: '', // 必填,生成签名的时间戳
  nonceStr: '', // 必填,生成签名的随机串
  signature: '',// 必填,签名,见 附录-JS-SDK使用权限签名算法
  jsApiList: [] // 必填,需要使用的JS接口列表,凡是要调用的接口都需要传进来
});

这里传的参数需要跟前端对接好,本文处理的参数为appId、timestamp、nonceStr、signature。

故创建WeComRespVO对象:
 

@Data
@Builder
public class WeComRespVO {

    /**
     * 时间戳
     */
    private String timestamp;
    /**
     * 随机字符串
     */
    private String noncestr;

    /**
     * 企业微信的corpID
     */
    private String appId;

    /**
     * 签名
     */
    private String signature;

}

主要的签名规则如下:

参与签名的参数有四个: noncestr(随机字符串), jsapi_ticket(如何获取参考“获取企业jsapi_ticket”、“获取应用的jsapi_ticket接口”以及“获取第三方应用的jsapi_ticket接口”), timestamp(时间戳), url(当前网页的URL, 不包含#及其后面部分)

注意事项:

  1. 字段值采用原始值,不要进行URL转义;
  2. 必须严格按照如下格式拼接,不可变动字段顺序。

拼接顺序:jsapi_ticket=JSAPITICKET&noncestr=NONCESTR&timestamp=TIMESTAMP&url=URL

拼接完后对拼接完字符串做sha1加密处理即可。

代码实例:

public WeComRespVO getSignature(String url) {
    String jsapiTicket = getJsapiTicket();
    //生成随机数(此处做简便处理,各位按各自方式生成)
    String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
    //时间戳
    String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
    //拼接,url是需要前端传进来的。
    String string1 = "jsapi_ticket=" + jsapiTicket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
    //对string1进行sha1签名,得到signature
    String signature = sha1Sign(string1);
    WeComRespVO weComRespVO = WeComRespVO.builder().signature(signature).noncestr(noncestr).timestamp(timestamp).appId(weComProperties.getClientId()).build();
    return weComRespVO;
}

private String sha1Sign(String input) {
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        md.update(input.getBytes());
        byte[] digest = md.digest();
        StringBuilder hexString = new StringBuilder();
        for (byte b : digest) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException("Unable to find SHA1 algorithm", e);
    }
}

整体代码如下:

@Data
@Builder
public class WeComRespVO {

    /**
     * 时间戳
     */
    private String timestamp;
    /**
     * 随机字符串
     */
    private String noncestr;

    /**
     * 企业微信的corpID
     */
    private String appId;

    /**
     * 签名
     */
    private String signature;

}

@Service
public class WeComClientServiceImpl implements WeComClientService {
    @Resource
    private WeComProperties weComProperties;

    @Resource
    private RedisTemplate redisTemplate;

    public String getAccessToken() {
        String weComAccessToken = (String) redisTemplate.opsForValue().get(WECOM_ACCESS_TOKEN);
        if (!StringUtils.isEmpty(weComAccessToken)) {
            return weComAccessToken;
        }
        try {
            String clientId = weComProperties.getClientId();
            String clientSecret = weComProperties.getClientSecret();
            String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + clientId + "&corpsecret=" + clientSecret;
            String resultStr = HttpUtil.get(url);

            JSONObject result = JSONObject.parseObject(resultStr);
            if (result == null) {
                throw exception(DATA_NOT_EXIST);
            }
            String accessToken = result.getString("access_token");
            String expiresIn = result.getString("expires_in");
            //存入redis
            redisTemplate.opsForValue().set(WECOM_ACCESS_TOKEN, accessToken,Long.valueOf(expiresIn), TimeUnit.SECONDS);
            return result.getString("access_token");
        } catch (ServiceException e) {
            throw new RuntimeException(e);
        }
    }

    public String getJsapiTicket() {
        String jsapiTicket = (String) redisTemplate.opsForValue().get(WECOM_JSAPI_TICKET);
        if (!StringUtils.isEmpty(jsapiTicket)) {
            return jsapiTicket;
        }
        try {
            String accessToken = getAccessToken();

            String url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=" + accessToken+"&type=agent_config";
            String resultStr = HttpUtil.get(url);
            JSONObject result = JSONObject.parseObject(resultStr);
            if (result == null) {
                throw exception(DATA_NOT_EXIST);
            }
            String ticket = result.getString("ticket");
            String expiresIn = result.getString("expires_in");
            //存入redis
            redisTemplate.opsForValue().set(WECOM_JSAPI_TICKET, ticket,Long.valueOf(expiresIn), TimeUnit.SECONDS);
            return result.getString("ticket");
        } catch (ServiceException e) {
            throw new RuntimeException(e);
        }
    }

    public WeComRespVO getSignature(String url) {
        String jsapiTicket = getJsapiTicket();
        //生成随机数
        String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
        //时间戳
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        //拼接
        String string1 = "jsapi_ticket=" + jsapiTicket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
        //对string1进行sha1签名,得到signature
        String signature = sha1Sign(string1);
        WeComRespVO weComRespVO = WeComRespVO.builder().signature(signature).noncestr(noncestr).timestamp(timestamp).appId(weComProperties.getClientId()).build();
        return weComRespVO;
    }

    private String sha1Sign(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            md.update(input.getBytes());
            byte[] digest = md.digest();
            StringBuilder hexString = new StringBuilder();
            for (byte b : digest) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();

        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Unable to find SHA1 algorithm", e);
        }
    }

}
  • 26
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: <?php $component_verify_ticket = $_GET['component_verify_ticket']; $url = "https://api.weixin.qq.com/cgi-bin/component/api_component_token"; $data = array( 'component_appid' => 'your_app_id', 'component_appsecret' => 'your_app_secret', 'component_verify_ticket' => $component_verify_ticket ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $output = curl_exec($ch); curl_close($ch); $jsoninfo = json_decode($output, true); $component_access_token = $jsoninfo["component_access_token"]; ### 回答2: <?php // 先获取 component_verify_ticket 参数 $componentVerifyTicket = $_GET['component_verify_ticket']; // 设置第三方平台的 appid 和 appsecret $appId = 'your_appid'; $appSecret = 'your_appsecret'; // 设置获取 component_access_token 的接口地址 $apiUrl = 'https://api.weixin.qq.com/cgi-bin/component/api_component_token'; // 构造请求参数 $data = array( 'component_appid' => $appId, 'component_appsecret' => $appSecret, 'component_verify_ticket' => $componentVerifyTicket ); // 发起 POST 请求获取 component_access_token $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $apiUrl); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $response = curl_exec($ch); curl_close($ch); // 解析返回数据 $result = json_decode($response, true); // 获取 component_access_token $componentAccessToken = $result['component_access_token']; // 打印 component_access_token echo 'component_access_token: ' . $componentAccessToken; ?> 以上代码是一个通过接收 component_verify_ticket 参数来直接获取 component_access_token 的示例。首先从 GET 请求中获取 component_verify_ticket 参数,然后设置之前申请第三方平台时获得的 appId 和 appSecret。之后构造请求参数,包括 component_appid、component_appsecret 和 component_verify_ticket,并将其作为 POST 请求的参数通过 curl 发起到获取 component_access_token 的接口地址。最后解析返回数据,获取到 component_access_token,并打印出来。 ### 回答3: PHP代码可以通过接收`component_verify_ticket`参数来直接获取`component_access_token`。下面是一个示例代码: ```php <?php // 获取微信推送的component_verify_ticket和component_appid $component_verify_ticket = $_GET['component_verify_ticket']; $component_appid = $_GET['component_appid']; // 定义请求的URL $url = 'https://api.weixin.qq.com/cgi-bin/component/api_component_token'; // 定义JSON请求参数 $data = [ 'component_appid' => $component_appid, 'component_appsecret' => 'YOUR_COMPONENT_APPSECRET', 'component_verify_ticket' => $component_verify_ticket, ]; // 发起POST请求 $options = [ 'http' => [ 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 'method' => 'POST', 'content' => http_build_query($data), ], ]; $context = stream_context_create($options); $response = file_get_contents($url, false, $context); // 解析响应数据 $result = json_decode($response, true); // 获取component_access_token $component_access_token = $result['component_access_token']; // 输出component_access_token echo $component_access_token; ?> ``` 以上代码接收通过GET请求传递的`component_verify_ticket`和`component_appid`参数,然后通过POST请求向微信服务器发送请求来获取`component_access_token`。注意需要将`YOUR_COMPONENT_APPSECRET`替换为真实的第三方平台的`component_appsecret`。最后将获取的`component_access_token`打印输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值