企业微信_企业微信转账到个人企业微信向微信账户转账 - CSDN
企业微信 订阅
企业微信是腾讯微信团队打造的企业通讯与办公工具,具有与微信一致的沟通体验,丰富的OA应用,和连接微信生态的能力,可帮助企业连接内部、连接生态伙伴、连接消费者。专业协作、安全管理、人即服务。目前企业微信已覆盖零售、教育、金融、制造业、互联网、医疗等50多个行业,正持续向各行各业输出智慧解决方案。 [1] 展开全文
企业微信是腾讯微信团队打造的企业通讯与办公工具,具有与微信一致的沟通体验,丰富的OA应用,和连接微信生态的能力,可帮助企业连接内部、连接生态伙伴、连接消费者。专业协作、安全管理、人即服务。目前企业微信已覆盖零售、教育、金融、制造业、互联网、医疗等50多个行业,正持续向各行各业输出智慧解决方案。 [1]
信息
软件版本
V3.0.2
软件平台
iOS、Android、Windows、Mac
软件语言
简体中文
软件大小
107.56MB [2]
开发商
腾讯
软件名称
企业微信
软件类型
办公平台
更新时间
2020年1月15日
推出时间
2016年4月18日
企业微信发展历程
2016年4月18日,企业微信1.0版本上线,连接企业内部每个人2017年6月29日,企业微信2.0版本上线,连接企业内部办公系统2017年,企业微信开放生态,连接生态伙伴2018年3月,企业微信与微信消息互通内测2018年8月,企业微信开放硬件接口,为企业提供软硬一体的解决方案2019年1月,企业微信定制红包封面上线2019年8月,企业微信获得SOC2Type2报告 [3]  2019年12月23日,企业微信3.0版本上线,正式连接微信生态,优化效率工具 [1] 
收起全文
  • 想接收企业微信的消息,首先得开启验证信息API(GET请求)以及接收消息服务(POST请求)。 GET的请求参考: 企业微信验证接口API 第一部分解析POST请求: 并且解析msg_signature, time, nonce和消息体数据Body...

    想接收企业微信的消息,首先得开启验证信息API(GET请求)以及接收消息服务(POST请求)。

    GET的请求参考:

    企业微信验证接口API

    第一部分解析POST请求:
    并且解析msg_signature, time, nonce和消息体数据Body(如下代码中POST的部分)

    @app.route('/blackcat/v1/receive_task', methods=['POST', 'GET'])
    def receive():
        try:
            auth_verify = AuthVerify()
            if request.method == "POST":
                msg_signature = request.args.get('msg_signature')
                timestamp = request.args.get('timestamp')
                nonce = request.args.get('nonce')
                request_data = request.data
                param = auth_verify.verifi_content(msg_signature, timestamp, nonce, request_data)
                submit_task_receive.delay(param)
            if request.method == "GET":
                msg_signature = request.args.get('msg_signature')
                timestamp = request.args.get('timestamp')
                nonce = request.args.get('nonce')
                echostr = request.args.get('echostr')
                s_echo_str = auth_verify.verifi(msg_signature, timestamp, nonce, echostr)
                return s_echo_str
        except Exception as e:
            print(e)
            return jsonify({'code': -1, 'error_message': e})

    然后通过解密用户输入的消息代码如下:

    这里可以解析出来

    会话时间:CreateTime

    消息发起者:FromUserName

    消息的内容:Content

    auth_verify.verifi_content(msg_signature, timestamp, nonce, request_data)
        def verifi_content(self, msg_signature, timestamp, nonce, request_data):
            ret, sMsg = self.wxcpt.DecryptMsg(request_data, msg_signature, timestamp, nonce)
            if ret != 0:
                print "ERR: DecryptMsg ret: " + str(ret)
                sys.exit(1)
            xml_tree = ET.fromstring(sMsg)
            content = xml_tree.find("Content").text
            create_time = xml_tree.find("CreateTime").text
            from_username = xml_tree.find("FromUserName").text
            return {'create_time': create_time, 'from_username': from_username, 'content': content}

     

    展开全文
  • 企业微信教程有:“标准版”和“在线版”。正常的,学习“标准版”可以完成企业微信的相关开发。“在线版”是“一对一在线班讲解”,针对同学们项目遇到的问题,个性化定制课程大纲,解决具体问题。“一对一在线班...
  • 企业微信_Java_项目版

    2019-03-11 09:44:22
    针对企业微信项目开发遇到的AccessToken缓存,整合企业微信OA的企业微信打卡、企业微信审批、企业微信公费电话等知识点进行讲解。 课程给出蒲公英解决企业微信外网访问局域网的解决方案。
  • 该课程是“企业微信视频教程Python3加强版"的免费赠阅部分 购买“企业微信视频教程Python3加强版"链接https://edu.csdn.net/course/detail/18628
  • 企业微信教程有:“标准版”和“在线版”。正常的,学习“标准版”可以完成企业微信的相关开发。“在线版”是“一对一在线班讲解”,针对同学们项目遇到的问题,个性化定制课程大纲,解决具体问题。“一对一在线班...
  • 准备工作 首先得注册个企业微信 其次下载一个加解密的包,免得自己封装 https://work.weixin.qq.com/api/doc#10128/java%E5%BA%93 具体使用方法:下载解压后,将com文件夹拷贝到src下,然后将lib下的jar包拷贝... ...

    今日头条搜索三线城市程序员老陈观看视频教程,或者聊聊技术与人生,非常欢迎吭。

    准备工作

    首先得注册个企业微信

    其次下载一个加解密的包,免得自己封装
    https://work.weixin.qq.com/api/doc#10128/java%E5%BA%93

    具体使用方法:下载解压后,将com文件夹拷贝到src下,然后将lib下的jar包拷贝到咱们web工程的WEB-INF/lib下就行了。

    创建应用

    登录企业微信,点击【企业应用】-【创建应用】,输入应用logo、应用名称,选择部门/成员后点击【创建应用】。

    #设置接收微信消息的开发者服务器

    点击刚刚创建的应用,点击【接收消息】-【设置API接收】,在URL处填写我方的地址,例如:

    http://xx.xx.xx.xx:8080/XXproject/XXServlet,表示IP地址xx.xx.xx.xx的8080端口上的XXproject项目的XXSerlvet负责接收微信发送的消息。

    然后点击Token和EncodingAESKey后的随机获取,将这两个参数记录下来。

    然后消息类型都选上,点击【保存】,此时提示"回调URL校验失败",所以需要在刚刚自己的Servlet上处理微信发过来的消息并按规则进行回复,这样微信才认可。

    验证URL

    首先封装一个常量类,保存相关参数,因为是企业微信Enterprise Wechat,此处简写为Wxep,此处为了安全就不具体写参数了

    	package com.easy.wxep.util;
    	/**
    	 * 企业微信常量
    	 * @author easypanda
    	 * @since 2018-04-21
    	 */
    	public class WxepConstants {
    		//API接收消息中的Token
    		public final static String Token="";
    		//API接收消息中的EncodingAESKey
    		public final static String EncodingAESKey="";
    		//企业ID
    		public final static String CorpId="";
    		//应用凭证密钥
    		public final static String CorpSecret="";
    	}
    	
    

    第二,在Servlet中对微信发过来的消息处理,注意加解密使用之前导入的jar包封装的接口即可。此处我用的是SpringMVC接收消息,在Servlet中代码一样即可。

    	/**
    	 * 接收企业微信api消息
    	 * @throws IOException 
    	 */
    	@RequestMapping("/public_wxapi_message")
    	public void public_wxapi_message(HttpServletRequest request, HttpServletResponse response) throws IOException {
    		//获取微信服务器发送过来的四个参数
    		//微信加密签名  
            String msg_signature = request.getParameter("msg_signature");  
            //时间戳  
            String timestamp = request.getParameter("timestamp");  
            //随机数  
            String nonce = request.getParameter("nonce");  
            //随机字符串  
            String echostr = request.getParameter("echostr");  
      
         
            //验证输入后返回消息给微信服务器
            PrintWriter out = response.getWriter();  
            // 通过检验msg_signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败  
            String result = null;  
            try {
                WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WxepConstants.Token, WxepConstants.EncodingAESKey, WxepConstants.CorpId);  
                result = wxcpt.VerifyURL(msg_signature, timestamp, nonce, echostr);  
            } catch (Exception e) {  
                e.printStackTrace();  	
            }  
            if (result == null) {  
                result = WxepConstants.Token;  
            }  
            out.print(result);  
            out.close();  
            out = null;  
    	}
    

    此时再点击【保存】则Eclipse异常信息:Illegal key size

    此时可参考企业微信API提出的方案:

    异常java.security.InvalidKeyException:illegal Key Size的解决方案:在官方网站下载JCE无限制权限策略文件(请到官网下载对应的版本, 例如JDK7的下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html ):下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt。
    如果安装了JRE,将两个jar文件放到%JRE_HOME% \lib\security目录下覆盖原来的文件,如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件。
    

    此处我使用的JDK8对应下载地址http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

    验证

    重启Tomcat后再次点击【保存】,提示"保存成功",表示微信服务器已认可我们配置的服务器。

    展开全文
  • 最近在搞企业微信的东西,刚开始对这个的确没有任何的概念,属于两眼抓瞎的类型,因为场景比较特殊网上搜到的资料也不多,只能自己看着官方文档一点一点去调试。于是,一系列的踩坑之路就上演了,这里就简单介绍一下...

    最近在搞企业微信的东西,刚开始对这个的确没有任何的概念,属于两眼抓瞎的类型,因为场景比较特殊网上搜到的资料也不多,只能自己看着官方文档一点一点去调试。于是,一系列的踩坑之路就上演了,这里就简单介绍一下笔者自己踩的坑吧,也为其他刚刚接触企业微信开发者朋友们提供一点借鉴。

    首先,要明确两个概念,就是微信和企业微信不是一个东西(虽然有些信息互通)、企业微信应用和服务商的第三方应用也不是一个东西(虽然也有些接口可以调用),企业内部开发指的是开发某个企业自己用的应用,而第三方应用开发指的就是开发者作为服务商开发第三方应用,让其他企业(使用企业微信的人)安装你(服务商)开发的应用。此处重点介绍下笔者作为服务商第三方应用的开发过程吧!(如下图是企业微信官方文档,上面有企业内部开发和第三方应用开发)
    在这里插入图片描述

    需要的准备:注册两个企业,一个作为应用的服务商,一个作为应用的使用者,使用服务商的企业登陆到服务商的管理平台。此处需要注意的是,企业微信有两个管理平台,一个是企业微信管理后台另一个是服务商管理平台,不要登陆错了。
    企业微信管理后台:https://work.weixin.qq.com/wework_admin
    企业微信服务商管理后台:https://open.work.weixin.qq.com/wwopen/developer
    企业微信管理后台
    企业微信服务商平台
    第一步,在服务商平台创建一个应用,将需要填写的信息填入。基础信息可以根据实际情况填写,开发信息可能刚接触的时候并不清楚如何填写,这里可以暂时先写随便写一个,后面可以修改并且需要认证,下文会将用到的一一进行介绍。
    在这里插入图片描述
    在这里插入图片描述
    第二步,信息介绍
    1.基本信息,在基本信息中尤其要注意的是suiteId和secret,suiteId是用于标记用于的唯一标识,secret是用于加解密的秘钥,尤其是secret,千万不能泄露。
    在这里插入图片描述
    2.使用配置,应用主页是企业安装第三方应用之后,跳转的主页页面;可信域名是企业微信进行授权和前端使用JS-SDK的时候校验的域名,若是域名不一致企业微信会报错;安装完成回调域名是在企业进行安装应用之后回调接口的域名;业务设置URL笔者没有用到,没有进行深究
    在这里插入图片描述
    3.回调配置,数据回调URL笔者没有用到,也是随便写了一个;指令回调URL,这个千万要注意,在后面获取到suite_ticket(应用ticket)的时候就需要用他;Token和EncodingAESKey,自动生成填上就行,不过不要随便去更改,因为这边更改的话,后面解密信息的时候就需要更改代码中的这两个值。
    在这里插入图片描述
    比较重要的信息就是这些,因为笔者自己的需要这边没有用到业务设置URL和数据回调URL,若是有大神用到也希望不吝指出,这里感激不尽。

    第三步,开发文档,将以上信息了解了之后,还需要看下官方文档。因为笔者是作为java开发的角度来进行开发的,所以主要需要了解的是快速入门服务端开发API注意,此处文档区分第三方应用开发和企业内部开发,服务商开发第三方应用一定是第三方应用的那一篇文档,千万不要看错了!
    文档链接:https://work.weixin.qq.com/api/doc
    在这里插入图片描述
    1.快速开发,注意此处的三个场景:企业的、应用的和服务商的。在开发过程中一定要分清这三者的区别,这是重中之重,“企业的”是指登录者所属的企业;“应用的”是指开发者的第三方应用;“服务商的”是指应用所属的企业,这和登录的企业不一样,一定要区分清楚!(此处不分清楚,后面会有很多坑)
    在这里插入图片描述
    2.服务端API,这里就是主要获取需要的信息api都有,但此处要区分清楚应用的、企业的、服务商的、个人的信息,它们不可通用(如下文介绍的user_ticket和suite_ticket不是一个东西)
    在这里插入图片描述
    第四步:指令回调流程的建立,在第二步中说到指令回调Url,需要在这里进行配置(代码在这一步最后贴上),企业微信官方会每10分钟调用一次,或者手动点击“刷新Ticket”,或者在编辑完成确认的时候会进行回调。
    在这里插入图片描述

    指令回调的需要先参考这篇文档(其中有好几个需要注意的点)
    在这里插入图片描述
    注意点1:解密此处有demo,直接使用官方的即可
    在这里插入图片描述
    在这里插入图片描述
    注意点2:在使用java解密过程中,可能会出现异常java.security.InvalidKeyException:illegal Key Size,这是因为jdk本身有解密策略的限制(有限制的解密策略,好像是为了传输安全?),这需要去oracle官方下载无限制的解密策略,企业微信官方也给出了关于这个问题的解决方案(在解密demo代码的WXBizMsgCrypt类的注释中,如图)
    此处附上下载地址:
    JDK7:http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
    JDK8:http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
    在这里插入图片描述

    注意点3:验证回调和实际数据传输方式不同:验证是GET请求,解密后需要将明文的echostr返回回去,实际数据传输是POST请求,入参是xml格式传入(但是在链接上也会有解密需要的参数msg_signature、timestamp、nonce因此都要接收),需要返回success
    在这里插入图片描述
    在这里插入图片描述
    注意点4:此处数据类型可能有很多种,具体可以参考文档的这边,此处笔者只是接收了suite_ticket(应用ticket)类型进行处理
    在这里插入图片描述
    在这里插入图片描述
    以下是笔者自己写的demo的代码(此处用dom4j解析xml字符串):

    	@ResponseBody
        @RequestMapping(value = "/directCallback")
        public void directCallback(HttpServletRequest request, HttpServletResponse response) throws Exception {
    		System.out.println("----------------------------");
        	System.out.println("this is directCallback");
        	response.setCharacterEncoding("UTF-8");
        	
        	try {
    	    	String corpid = request.getParameter("corpid");
    	    	// 企业微信加密签名
    	        String msgSignature = request.getParameter("msg_signature");
    	        // 时间戳 与nonce结合使用,用于防止请求重放攻击
    	        String timestamp = request.getParameter("timestamp");
    	        // 校验时字符串
    	        String echostr = request.getParameter("echostr");
    	        // 随机数 与timestamp结合使用,用于防止请求重放攻击
    	        String nonce = request.getParameter("nonce");
    	        
    	        System.out.println("msgSignature: "+ msgSignature);
    	        System.out.println("timestamp: "+ timestamp);
    	        System.out.println("echostr: "+ echostr);
    	        System.out.println("nonce: "+ nonce);
    	    	if("GET".equals(request.getMethod())) { // get请求表示是验证
    	    		System.out.println("corpid:" + corpid);
    		        String echostrDecrypt = null;
    		        // 校验服务商公司id
    		        WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, corpid);
    				echostrDecrypt = wxcpt.VerifyURL(msgSignature, timestamp, nonce, echostr);
    				System.out.println("verifyurl echostr: " + echostrDecrypt);
    		    	
    		    	response.setCharacterEncoding("UTF-8");
    		    	response.getWriter().write(echostrDecrypt);
    	    	}else { // post请求表示是真实数据
    	    		// 获取传过来的xml信息(密文)
    	        	InputStream ins = request.getInputStream();
    	        	BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(ins));
    	        	StringBuilder postData = new StringBuilder();
    	        	String line = null;
    	        	while((line=bufferedReader.readLine()) != null) {
    	        		postData.append(line);
    	        	}
    	        	System.out.println("postData:"+ postData);
    	    		
    	    		WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, suiteid);
    	    		String info = wxcpt.DecryptMsg(msgSignature, timestamp, nonce, postData.toString());
    	    		System.out.println("解析的明文是:" + info); // 此处明文是xml信息
    	    		
    	    		// 解析xml,若InfoType是suite_ticket的话,说明是发送ticket的响应方式
    	        	Document doc = DocumentHelper.parseText(info);
    	        	Element root = doc.getRootElement();
    	        	String infoType = root.elementTextTrim("InfoType");
    	        	if("suite_ticket".equals(infoType)) { // 此处只是进行suite_ticket的处理,若是需要其他的处理需要在这里添加类型
    	        		String suiteTicket = root.elementTextTrim("SuiteTicket");
    	        		System.out.println("拿到的ticket是: " + suiteTicket);
    	        	}
    	    		
    	    		response.getWriter().write("success");
    	    	}
    	    	System.out.println("----------------------------");
    		} catch (Exception e) {
    			//验证URL失败,错误原因请查看异常
    			e.printStackTrace();
    		}
        }
    

    第五步:建立应用授权流程(注意主体是应用),此处不是登陆者登录之后授权才能用那个流程,而是在安装应用时候的授权流程。此时是为了获取应用的access_token(第三方应用凭证)和permanent_code(永久授权码),有了access_token和permanent_code,加上之前的suite_ticket(应用ticket),很多其他的信息就可以获取到了
    1.在服务商网站配置ip访问白名单,这一点不可忽略,否则无法访问
    在这里插入图片描述
    在这里插入图片描述
    2.获取企业的access_token(第三方应用凭证),此处ticket就是企业微信官方每10分钟推送的suite_ticket(应用ticket),还需要应用的id和应用的secret
    在这里插入图片描述
    3.安装应用获取auth_code(临时授权码),此处只是进行安装测试,若需要正式上线需要走上线流程
    在这里插入图片描述
    使用另一个企业进行此处的安装测试之后,之前实现的回调接口会接收到临时授权码的信息
    在这里插入图片描述
    在这里插入图片描述
    4.获取到permanent_code永久授权码
    在这里插入图片描述
    有了access_token、permanent_code和suite_ticket之后,很多的信息都可以获取到了

    第六步:用户登录时的用户授权流程,在用户登录的时候,需要用户授权应用,获取去到用户信息,将用户与第三方应用中的用户关联起来。此处,企业微信官方采用的是oauth2授权方式,oauth2授权流程可以参考文档此处--------此处请注意下后面的更新,有神坑!!!!!
    在这里插入图片描述
    1.构造oauth2授权链接,此处若是后面需要获取到用户的手机号、邮箱等敏感信息,必须要使用手动授权方式(即scope=snsapi_privateinfo),服务商管理后台中创建的应用,必须支持获取用户的敏感信息,这两个条件只要有一个不满足就无法获取到用户的手机号等敏感信息。
    在这里插入图片描述
    在这里插入图片描述
    构造的oauth2链接可以放在前端,也可以由后端配置后返回给前端,但是oauth2链接必须由前端跳转(不能由后端重定向,当然内部转发跳不到服务器之外的地址更不行),因为此处关联了设置的可信域名,可信域名关联前端使用的JS-SDK因此必须填前端域名
    在这里插入图片描述
    2.获取user_ticket(用户ticket),此处不能搞混user_ticket和suite_ticket,一个是用户的ticket,通过code获取;一个是应用的ticket,企业微信每10分钟推送给回调函数(笔者就搞混了,一直以为是哪里获取的不对导致获取不到用户信息)
    在这里插入图片描述
    3.若是还需要获取到用户的敏感信息,则根据access_token和user_ticket就可以拿到了,当然,是建立在可以拿到的前提下(应用允许获取、oauth2采用手动授权、用户同意授权)
    在这里插入图片描述
    获取到用户信息之后,就可以将企业微信的用户信息和业务的用户信息关联起来,主要的流程就可以疏通了!

    第七步:服务端配置客户端需要的签名signature等信息,在客户端的JS-SDK中,必须要先调用wx.config接口来进行权限的校验之后,才能够进行JS其他接口的调用,此时就需要服务端将签名signature、时间戳timestamp、随机串nonceStr、登录公司corpId返回,如下图
    在这里插入图片描述
    此处需要注意的点不少,只要有一点对不上,那么就可能造成流程走不下去。

    注意点1:
    使用JSSDK之前,一定要填写可信域名并且校验,否则JSSDK的接口无法使用。此处需要注意的点是,若是测试授权应用的话,进行验证之后,一定要重新安装才能生效,笔者就因为没有重新安装卡了很久,一直以为是配置的问题。
    在这里插入图片描述
    在这里插入图片描述

    注意点2:
    生成签名的算法需要参考客户端附录中的这篇文档(如图),由于之前第三方应用凭证已经获取到,此处jsapi_ticket也可以拿到了
    在这里插入图片描述
    注意点3:
    生成签名算法的时候,需要的url参数一定不要加上#后面的参数
    在这里插入图片描述
    注意点4:
    校验签名算法工具:https://work.weixin.qq.com/api/jsapisign
    此处只能校验签名是否正确,但是不能保证传入的url正确,因此需要确保传入的url包含“?”后面的参数但是不包含#后面的参数,如“http://xxx.xxx.xxx/xxx/?test=xxx”,可使用UUID生成nonceStr,再加上时间戳和url,将代码生成的signature和工具生成的signature进行校对保证生成算法的正确性
    在这里插入图片描述

    注意点5:
    在附录最后一篇中,有各种错误的结局方案,但是此处说要将生成signature进行转码,但是亲测转码之后是不行的,不转码可以
    在这里插入图片描述

    以上就是笔者疏通整个企业微信流程的踩过的坑,当然因为也是第一次接触,还有很多还不熟悉,可能还有很多谬误,若是读者发现那里不对,还望不吝指教!


    20190814更新
    更新遇到的两个神坑:
    神坑1.官方文档上提供了获取登录用户的手机号、邮箱等敏感信息
    在这里插入图片描述
    在构建oauth链接的时候,仅仅有一个“已废弃”的字样,可是在使用中还是可以继续使用的,到这里,一切还没有其他问题,正常使用。。。
    在这里插入图片描述
    于是!!!!!在上线审核的时候,获取用户敏感信息的应用,是审核不通过的!!!
    在这里插入图片描述
    找客服仔细确认之后(普通客服到技术客服到产品客服),才知道现在以后不支持获取用户敏感信息的应用上线的!!!!!(可能以后会支持,但是目前不支持,时间节点是20190814)

    神坑2.在服务商的应用中,是可以填写多个可信域名的(3个),但是亲测,只有第一个有效!!!另外的两个无论是构建oauth链接,还是使用jssdk(此处笔者调用的是wx.config这个jssdk无效,报错为not reliable domain),均无效(也是找客服确认后才知道,只有第一个是有效的)
    在这里插入图片描述

    展开全文
  • 以前写过一篇公众号的授权登录...1.网页授权及JS-SDK需要在企业微信上配置可信域名 2.企业微信授权登录里面填写你的可信域名 调用流程为: A) 用户访问第三方服务,第三方服务通过构造OAuth2链接...

    以前写过一篇公众号的授权登录https://blog.csdn.net/dsn727455218/article/details/65630151,今天给大家分享一下企业微信的授权登录。

    大致都差不多流程

    注意事项:

    1.网页授权及JS-SDK需要在企业微信上配置可信域名

    2.企业微信授权登录里面填写你的可信域名

    调用流程为:
    A) 用户访问第三方服务,第三方服务通过构造OAuth2链接(参数包括当前第三方服务的身份ID,以及重定向URI),将用户引导到认证服务器的授权页
    B) 用户选择是否同意授权
    C) 若用户同意授权,则认证服务器将用户重向到第一步指定的重定向URI,同时附上一个授权码。
    D) 第三方服务收到授权码,带上授权码来源的重定向URI,向认证服务器申请凭证。
    E) 认证服务器检查授权码和重定向URI的有效性,通过后颁发AccessToken(调用凭证)

    企业微信OAuth2接入流程

    使用OAuth2前须知

    关于网页授权的可信域名

    REDIRECT_URL中的域名,需要先配置至应用的“可信域名”,否则跳转时会提示“redirect_uri参数错误”。
    要求配置的可信域名,必须与访问链接的域名完全一致。举个例子:

    • 假定重定向访问的链接是:http://mail.qq.com:8080/cgi-bin/helloworld:
    配置域名 是否正确 原因
    mail.qq.com:8080 correct 配置域名与访问域名完全一致
    email.qq.com error 配置域名必须与访问域名完全一致
    support.mail.qq.com error 配置域名必须与访问域名完全一致
    *.qq.com error 不支持泛域名设置
    mail.qq.com error 配置域名必须与访问域名完全一致,包括端口号
    • 假定配置的可信域名是 mail.qq.com:
    访问链接 是否正确 原因
    https://mail.qq.com/cgi-bin/helloworld correct 配置域名与访问域名完全一致
    http://mail.qq.com/cgi-bin/redirect correct 配置域名与访问域名完全一致,与协议头/链接路径无关
    https://exmail.qq.com/cgi-bin/helloworld error 配置域名必须与访问域名完全一致

    关于UserID机制

    UserId用于在一个企业内唯一标识一个用户,通过网页授权接口可以获取到当前用户的UserId信息,如果需要获取用户的更多信息可以调用 通讯录管理 - 成员接口 来获取。

    缓存方案建议

    通过OAuth2.0验证接口获取成员身份会有一定的时间开销。对于频繁获取成员身份的场景,建议采用如下方案:
    1、企业应用中的URL链接直接填写企业自己的页面地址
    2、成员操作跳转到步骤1的企业页面时,企业后台校验是否有标识成员身份的cookie信息,此cookie由企业生成
    3、如果没有匹配的cookie,则重定向到OAuth验证链接,获取成员的身份信息后,由企业后台植入标识成员身份的cookie信息
    4、根据cookie获取成员身份后,再进入相应的页面

    构造网页授权链接

    如果企业需要在打开的网页里面携带用户的身份信息,第一步需要构造如下的链接来获取code参数:

    
     
    1. https://open.weixin.qq.com/connect/oauth2/authorize?appid=CORPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect

    参数说明:

    参数 必须 说明
    appid 企业的CorpID
    redirect_uri 授权后重定向的回调链接地址,请使用urlencode对链接进行处理
    response_type 返回类型,此时固定为:code
    scope

    应用授权作用域。

    snsapi_base:静默授权,可获取成员的基础信息;
    snsapi_userinfo:静默授权,可获取成员的详细信息,但不包含手机、邮箱;
    snsapi_privateinfo:手动授权,可获取成员的详细信息,包含手机、邮箱。

    state 重定向后会带上state参数,企业可以填写a-zA-Z0-9的参数值,长度不可超过128个字节
    #wechat_redirect 终端使用此参数判断是否需要带上身份信息
    agentid 企业应用的id。
    当scope是snsapi_userinfo或snsapi_privateinfo时,该参数必填。
    注意redirect_uri的域名必须与该应用的可信域名一致。


    员工点击后,页面将跳转至 redirect_uri?code=CODE&state=STATE,企业可根据code参数获得员工的userid。code长度最大为512字节。

    权限说明:
    企业无限制;第三方使用snsapi_privateinfo的scope时,应用必须有’成员敏感信息授权’的权限。

    根据code获取成员信息
    请求方式:GET(HTTPS)
    请求地址:https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE

    参数说明:

    参数    必须    说明
    access_token    是    调用接口凭证
    code    是    通过成员授权获取到的code,最大为512字节。每次成员授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。

    权限说明:
    跳转的域名须完全匹配access_token对应应用的可信域名。

    返回结果:
    a) 当用户为企业成员时返回示例如下:

    {
    "errcode":0,
    "errmsg":"ok",
    "UserId":"USERID",
    "DeviceId":"DEVICEID",
    "user_ticket":"USER_TICKET",
    "expires_in":7200
    }

    参数    说明
    errcode    返回码
    errmsg    对返回码的文本描述内容
    UserId    成员UserID
    DeviceId    手机设备号(由企业微信在安装时随机生成,删除重装会改变,升级不受影响)
    user_ticket    成员票据,最大为512字节。
    scope为snsapi_userinfo或snsapi_privateinfo,且用户在应用可见范围之内时返回此参数。
    后续利用该参数可以获取用户信息或敏感信息。
     
    expires_in    user_token的有效时间(秒),随user_ticket一起返回
    非企业成员授权时返回示例如下:

    {
    "errcode":0,
    "errmsg":"ok",
    "OpenId":"OPENID",
    "DeviceId":"DEVICEID"
    }


    参数    说明
    errcode    返回码
    errmsg    对返回码的文本描述内容
    OpenId    非企业成员的标识,对当前企业唯一
    DeviceId    手机设备号(由企业微信在安装时随机生成,删除重装会改变,升级不受影响)
    出错返回示例:

    {
    "errcode":40029,
    "errmsg":"invalid code"
    }
     

    实现代码:

    package com.eqiao.bidata.weixin.controller;
     
    import com.eqiao.bidata.weixin.common.AccessToken;
    import com.eqiao.bidata.weixin.common.Result;
    import com.eqiao.bidata.weixin.common.WeiXinQiYeConstants;
    import com.eqiao.bidata.weixin.common.WeiXinQiYeUtil;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    import java.io.UnsupportedEncodingException;
     
    /**
     * 单纯实现OAuth2验证,不使用注解及拦截器
     * Created by zhaoxinguo on 2017/7/11.
     */
    @Controller
    public class SimpleOAuth2Controller {
     
        private Logger logger = LoggerFactory.getLogger(SimpleOAuth2Controller.class);
     
        /**
         * 拼接网页授权链接
         * 此处步骤也可以用页面链接代替
         * @return
         */
        @RequestMapping(value = { "/oauth2wx.do" })
        public String Oauth2API(HttpServletRequest request){
            //获取项目域名
            String requestUrl = request.getServerName();
            String contextPath = request.getContextPath();
            logger.info("domain name: " + requestUrl + " project name: " + contextPath);
            //拼接微信回调地址
            String backUrl ="http://" + requestUrl + contextPath + "/oauth2me.do";
            String redirect_uri = "";
            try {
                redirect_uri = java.net.URLEncoder.encode(backUrl, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                logger.error("ecdoe error: " + e.getMessage());
            }
            String oauth2Url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WeiXinQiYeConstants.CORPID + "&redirect_uri=" + redirect_uri
                    + "&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
            return "redirect:" + oauth2Url;
        }
     
        /**
         * 授权回调请求处理
         * @return
         */
        @RequestMapping(value = { "/oauth2me.do" })
        public String oAuth2Url(HttpServletRequest request, @RequestParam String code){
            // 调用获取access_token的接口
            AccessToken accessToken = WeiXinQiYeUtil.access_token();
            HttpSession session = request.getSession();
            if (accessToken != null && accessToken.getAccess_token() != null) {
                // 调用获取用户信息的接口
                String UserId = getMemberGuidByCode(accessToken.getAccess_token(), code, WeiXinQiYeConstants.AGENTID);
                logger.info("UserId: " + UserId);
                if (UserId != null) {
                    session.setAttribute("UserId", UserId);
                    logger.info("UserId放入session成功!");
                }
            }
            // 这里简单处理,存储到session中
            return "user/result";
        }
     
        /**
         * 调用接口获取用户信息
         *
         * @param token
         * @param code
         * @return
         */
        public String getMemberGuidByCode(String token, String code, String agentId) {
            logger.info("code==" + code + " token=" + token + " agentId=" +agentId);
            Result result = WeiXinQiYeUtil.oAuth2GetUserByCode(token, code, agentId);
            logger.info("result= " + result);
            if (result.getErrcode().equals("0")) {
                if (result.getUserId() != null  && result.getUserId().length() > 0) {
                    // 此处可以通过微信授权用code还钱的Userid查询自己本地服务器中的数据
                    logger.info("result.getUserId(): " + result.getUserId());
                    return result.getUserId();
                }
            }
            return "";
        }
     
    }
    
    /**
         * OAuth2验证接口根据code获取成员信息
         *
         * @param token
         * @param code
         * @return
         */
        public static Result oAuth2GetUserByCode(String token, String code, String agentId) {
            Result result = new Result();
            String menuUrl = WeiXinQiYeConstants.GET_OAUTH2_URL.replace("ACCESS_TOKEN", token).replace("CODE", code).replace("AGENTID", agentId + "");
            String userinfo = JHttpUtils.doGet(menuUrl);
            logger.info("userinfo: " + userinfo);
            JSONObject jsonObject = null;
            if (userinfo != null) {
                try {
                    jsonObject = JSONObject.fromObject(userinfo);
                    logger.info("jsonObject: " + jsonObject);
                    if (jsonObject.getString("UserId") != null && jsonObject.getString("UserId").length() > 0) {
                        result.setErrmsg(jsonObject.getString("errmsg"));
                        result.setErrcode(jsonObject.getString("errcode"));
                        result.setUserId(jsonObject.getString("UserId"));
                    } else {
                        result.setErrmsg(jsonObject.getString("errmsg"));
                        result.setErrcode(jsonObject.getString("errcode"));
                    }
                } catch (Exception e) {
                    result.setErrmsg("accessToken 超时......");
                    result.setErrcode("42001");
                }
            }
            return result;
        }
    
    

    一个完整的流程就是这样。

    如遇到问题欢迎进群308742428

    喜欢的朋友可以关注下,粉丝也缺。

    展开全文
  • 跳坑记录 要成为第三方供应商,先按开发文档步骤操作。...系统事件接收URL:保存之前腾讯的企业微信服务器会发送一个Get请求到这个地址,所有要准备一台服务器,接受这请求,并做URL验证。 验证URL有效...

    跳坑记录

    要成为第三方供应商,先按开发文档步骤操作。服务商注册应用。也可以申请个企业微信帐号,然后成为服务商(可以做测试,但应用不能上线)

    1,注册成功后,配置开发信息:通用开发参数

    这里的CorpID是第三方供应商供应商的企业ID,不同于企业微信的CorpID。 ProviderSecret:还未用到,之后再补
    系统事件接收URL:保存之前腾讯的企业微信服务器会发送一个Get请求到这个地址,所要要准备一台服务器(也可以用内网穿透工具实现),接受这请求,并做URL验证。
    验证URL有效性

    Token、EncodingAESKey:这个Token+EncodingAESKey+腾讯微信服务器的Get请求的QueryString,一起来解密Get请求的密文,并返回明文,解析正确并Response.Write(明文),也就验证URL成功了。

    这里写图片描述

    2, 创建应用,并配置

    SuiteID:指令回调URL 解密时使用。数据回调URL解密时使用的是安装第三方应用的授权方的CorpID。如果错误,解密会返回40005
    错误的CorpID。

    Secret:和SuiteID一起用来获取应用授权Token

    这里写图片描述

    应用主页:要设计的应用主页 可信域名:还不清楚,之后再补 业务设置URL:安装第三方应用的企业(授权方)管理员进入应用后台配置的URL
    数据回调URL:这里也是要先验证,与前面的系统事件接收URL验证方式一样,要处理腾讯企业微信服务器的Get请求并返回解密后的明文,验证后,处理接收消息时是POST请求
    指令回调URL:使用时感觉就是接收Event的,指令理解为事件更好理解吧。与前面的系统事件接收URL验证方式一样,要处理腾讯企业微信服务器的Get请求并返回解密后的明文,验证后,处理接收消息时是POST请求

    这里写图片描述

    应用主页配置

    前面未对应用主页说明,自己在学习中也遇到诸多问题,问题列表与解决办法:

    1. 自定义菜单怎么在应用主页上显示?:到目前没解决。如果是企业应用而不是第三方应用的话,只要不设置应用主页,在进入应用时直接回显示自定义的菜单。
    2. 怎么将授权方和我做的第三方应用联系起来? 这个问题搞了两天才大概的了解 :
      1. 先仔细阅读开发文档 链接1网页授权登录 ,链接2网页授权登录第三方
        。要清楚了解链接1中的 OAuth2.0接入流程说明,因为是做的第三方应用,链接2页必须要仔细阅读。
      2. 了解后发现,之前的应用主页设置的有问题,应用主页要写成下面的形式(可能不完全正确),redirect_uri的域名一定要与【可信域名】一致,如果可信域名是二级,这里也要设置为二级域名。
      3. 以上两点了解后,参考 企业微信第三方应用配置
        ,终于能将 企业微信和第三方应用串联起来了。
      4. 第三方应用里,想要创建主菜单、二级菜单、view菜单、click菜单怎么做?:貌似全要由第三方自己实现了。前面说了,非第三方的企业应用只要不设置主页就可以直接使用企业微信后台设置的自定义菜单

    第三方应用里的自定义菜单的界面是当有消息时才会看到,不是用来设计应用,而是作为第三方应用的入口:比如点选哪个菜单跳转到第三方应用的那个网址、点选哪个菜单执行拍照、图片选取、录音什么的。但第三方应用要求必须设置应用主页,菜单不就显示不出来了。
    这里写图片描述

    展开全文
  • 欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践...腾讯企业微信产品部行业运营中心高级总监王宏岩,在政务专场上做了以《互联网的发展与企业微信》为主题的分享,以下内容整理自演讲。 大家好!我是来自企业微...
  • 讲课大师现在可以把微信中的语音、文字、图片等消息,转播到企业微信中了。开发这个功能,花了快三周的时间,主要是各种事情把我弄得太苦逼,让我无法集中精力,感谢上海杜总红包的鼓励,现在终于可以发布第一个版本...
  • 本系列课程主要讲述如何利用Servlet3.0+JDBC+Bootstrap+MYSQL+Ajax+构建企业级应用解决方案,主要分为两部分完成第一部分:设计部分,通过需求分析,设计物理模型,画出原型界面(HTML)第二部分:编码部分,具体实现...
  • 企业微信开发

    2018-05-10 15:19:32
    企业微信的认识企业微信概念:企业微信2016年4月18日,腾讯正式发布全平台企业办公工具“企业微信”。与微信一致的沟通体验,为企业员工提供最基础和最实用的办公服务,并加入贴合办公场景的特色功能、轻OA工具,提供...
  • 项目最近安全升级,引入了企业微信动态码登录,分别为:企业微信动态码和企业微信扫码登录的两种方式。这里我负责的主要是企业微信动态码这个功能,这里简单的写一下我是怎么做的。 开发人员首先要了解企业微信的API...
  • 企业微信第三方应用上架:在企业微信上,第三方应用想要上架到企业微信的应用市场,首先需要成为服务商,申请成功之后才能走应用上架流程。 其实申请成为服务商不难,难就难在于你要将应用上传到企业微信的应用...
  • * @override overview 自动打开企业微信,自动从微信好友中添加并发送邀请,包括显示控制台打印日志。 * 可加V交流:niu17550211709 * */ auto.waitFor(); var height = device.height; var width = device....
  •  具体而言,就是可以把在企业微信后台做的事情,搬到自己的项目中完成,举个例子:我们可以在企业微信后台对成员进行增删改查的操作,当我们把企业微信接入自己的项目中时,我们可以调用企业微信的接口在自己的项目...
  • 原来系统中报警采用短信和邮件方式,短信采用阿里的短信,近期由于 一些原因,项目中想将报警信息发送到 企业微信中,由于之前小编玩zabbix的时候实现过这个需求,所以认为通过java应该比较简单, 下面分享接入代码...
  • 项目上为了支持新的业务,扩展了通过企业微信扫码登录和通过企业微信容器内的直接访问应用服务的免密登录。 1.扫码登录 企业微信以Userid作为企业内的用户身份唯一标识,集成接口可以参考官网文档: ...
  • 企业微信是免费使用的,是腾讯2016年推出的战略级产品,是一款对内也可以对外沟通的即时通讯和办公软件。企业微信与个人微信实现消息互通,用企业微信连接10亿客户,让工作更高效,让聊天更愉悦! 企业微信继承了...
1 2 3 4 5 ... 20
收藏数 136,714
精华内容 54,685
关键字:

企业微信