企业微信wecom/jssdk的使用(入门)

发布于:2025-06-24 ⋅ 阅读:(14) ⋅ 点赞:(0)

概述

记录一个企业微信jssdk的使用,因为要用到图片上传、扫描二维码等工具。项目是uniapp开发的h5项目,fastadmin(thinkphp5)后端

先看官方文档

https://developer.work.weixin.qq.com/document/path/90547#%E5%BA%94%E7%94%A8%E8%BA%AB%E4%BB%BD%E6%B3%A8%E5%86%8Chttps://developer.work.weixin.qq.com/document/path/90547#%E5%BA%94%E7%94%A8%E8%BA%AB%E4%BB%BD%E6%B3%A8%E5%86%8C

一、安装sdk

安装及使用按照官方文档的操作,安装完之后重启一下编辑器! 

二、接口鉴权

接口鉴权有两种方式,一种是企业身份注册,一种是应用身份注册。

这里我选择了应用注册。

涉及到js-sdk签名算法,见下面的官方文档:

https://developer.work.weixin.qq.com/document/path/90506

如果已经实现了可以继续往下。这里展开说说怎么做(前端的童鞋可以先回避,这里依靠后端实现)。

对应的后端代码,但是我这里实测是签名无效的,不知道问题出现在哪里,最后选择 把ticket返回给前端,用官方的签名算法去计算签名。

    /**
     * 企业微信JS-SDK配置接口
     */
    public function wwregister()
    {
        $url = $this->request->post('url');
        if (!$url) {
            $this->error('缺少URL参数');
        }
        
        try {
            // 1. 获取access_token
            $accessToken = $this->getAccessToken();
            
            // 2. 获取企业级jsapi_ticket
            $jsapiTicket = $this->getJsapiTicket($accessToken);
            
            // 3. 获取应用级jsapi_ticket
            $appJsapiTicket = $this->getAppJsapiTicket($this->app_id, $this->app_secret);
            
            // 4. 生成企业签名和应用签名
            $configSignature = $this->generateConfigSignature($jsapiTicket, $url);
            $agentConfigSignature = $this->generateAgentConfigSignature($appJsapiTicket, $url);
            
            // 5. 构建响应数据
            $config = [
                'corpId' => $this->corpid,
                'agentId' => $this->app_id,
                'jsApiList' => ['chooseImage', 'scanQRCode'],
                'configSignature' => $configSignature,
                'agentConfigSignature' => $agentConfigSignature,
                'timestamp' => $configSignature['timestamp'],
                'nonceStr' => $configSignature['nonceStr'],
                'tk1'=>$jsapiTicket,
                'tk2'=>$appJsapiTicket
            ];
            
            $this->success('获取成功', $config);
        } catch (Exception $e) {
            $this->error('获取失败: ' . $e->getMessage());
        }
    }
    
    /**
     * 生成企业级签名
     */
    private function generateConfigSignature($jsapiTicket, $url)
    {
        $timestamp = time();
        $nonceStr = $this->createNonceStr();
        
        // 拼接签名参数
        $string = "jsapi_ticket={$jsapiTicket}&noncestr={$nonceStr}&timestamp={$timestamp}&url={$url}";
        
        // 计算SHA1签名
        $signature = sha1($string);
        
        return [
            'timestamp' => $timestamp,
            'nonceStr' => $nonceStr,
            'signature' => $signature
        ];
    }
    
    /**
     * 生成应用级签名
     */
    private function generateAgentConfigSignature($appJsapiTicket, $url)
    {
        $timestamp = time();
        $nonceStr = $this->createNonceStr();
        
        // 拼接签名参数
        $string = "jsapi_ticket={$appJsapiTicket}&noncestr={$nonceStr}&timestamp={$timestamp}&url={$url}";
        
        // 计算SHA1签名
        $signature = sha1($string);
        
        return [
            'timestamp' => $timestamp,
            'nonceStr' => $nonceStr,
            'signature' => $signature
        ];
    }
    

 /**
     * 获取应用jsapi_ticket
     */
    private function getAppJsapiTicket($agentid,$appsecret)
    {
        // 从缓存获取或重新请求
        $jsapiTicket = Cache::get($agentid.'wecom_appjsapi_ticket');
        if (!$jsapiTicket) {
            // 这里应该拿应用的accesstoken
            $accessToken = getAppAccessToken($agentid,$appsecret);
            // 跟获取企业jsapi_ticket的却别在与请求的url不一样
            $url = "https://qyapi.weixin.qq.com/cgi-bin/ticket/get?access_token={$accessToken}&type=agent_config";
            $result = $this->httpGet($url);
            $result = json_decode($result, true);
            
            if (isset($result['ticket'])) {
                $jsapiTicket = $result['ticket'];
                Cache::set($agentid.'wecom_appjsapi_ticket', $jsapiTicket, 7100); // 提前100秒过期
            } else {
                throw new Exception('获取jsapi_ticket失败: ' . json_encode($result));
            }
        }
        
        return $jsapiTicket;
    }

    // 获取应用的accesstoken
    public function getAppAccessToken($agentid,$appsecret)
    {
        $token = Cache::get($agentid.'_wecom_access_token');
        if (!$token) {
            $config = get_addon_config('wecom');
            $corpid = $this->corpid;
            $corpsecret = $appsecret;
            $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$corpid}&corpsecret={$corpsecret}";
            $result = $this->httpGet($url);
            $result = json_decode($result, true);
             
            if (isset($result['access_token'])) {
                $accessToken = $result['access_token'];
                Cache::set($agentid.'_wecom_access_token', $accessToken, 7100); // 提前100秒过期
            } else {
                throw new Exception('获取access_token失败: ' . json_encode($result));
            }
        }
        return $token;
    }


    /**
     * 获取access_token
     */
    private function getAccessToken()
    {
        // 从缓存获取或重新请求
        $accessToken = Cache::get('wecom_access_token');
        if (!$accessToken) {
            $corpid = $this->corpid;
            $corpsecret = $this->corpsecret;
            
            $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$corpid}&corpsecret={$corpsecret}";
            $result = $this->httpGet($url);
            $result = json_decode($result, true);
            
            if (isset($result['access_token'])) {
                $accessToken = $result['access_token'];
                Cache::set('wecom_access_token', $accessToken, 7100); // 提前100秒过期
            } else {
                throw new Exception('获取access_token失败: ' . json_encode($result));
            }
        }
        
        return $accessToken;
    }
    

回到前端,在页面中写方法

三、遇到的问题

1、项目调试使用微信开发者工具;

2、项目本地开发,会报错“invalid url domain”

打包线上之后正常,是否只能一边改一边打包上线测试呢~我也没搞清楚是否有解决办法,不然不大方便啊!!

项目上线后,可以成功拿到jssdk权限 

3、invalid signature

上面已经提到过了,如果拿后端返回的签名是无效的(当然不排除我写的后端方法有问题~)

虽然官方文档给出排错的文档,但是对接的心好累,下回分解了~

四、接口的使用:选择图像

经过大费周章的前期准备,万事俱备,终于可以正常使用工具了,例如图像选择

	// 选择图片
	const chooseImage = () => {
		if (images.value.length >= 5) {
			uni.showToast({
				title: '最多上传5张图片',
				icon: 'none'
			});
			return;
		}

		ww.chooseImage({
			count: 5 - images.value.length, // 最多可以选择的图片张数
			sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
			sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
			success: (res : any) => {
				// 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
				const localIds = res.localIds;

				// 上传图片到微信服务器并获取服务器ID
				localIds.forEach((localId : string) => {
					uploadImageToWechat(localId);
				});
			},
			fail: (err : any) => {
				console.error('选择图片失败', err);
				uni.showToast({
					title: '选择图片失败',
					icon: 'none'
				});
			}
		});
	};

 

看到这个窗口,前期准备功夫全不费工夫,终于可以上传文件了。

但是这仅仅是开始~图片会上传到企微服务器,还得拉下来保存到自己的服务器。又可以另外写一篇文章叙述了。


网站公告

今日签到

点亮在社区的每一天
去签到