热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Force.com微信企业号开发系列-启用二次验证

微信于9月份推出企业号后引起了业界不小的反响,许多企业都在思索企业号将如何影响企业的运营,从本文开始,我将详细阐述微信企业号开发的相关知识,而本文将着重介绍如何实现更高安全机制的二次验证。

微信于9月份推出企业号后引起了业界不小的反响,许多企业都在思索企业号将如何影响企业的运营,从本文开始,我将详细阐述微信企业号开发的相关知识,而本文将着重介绍如何实现更高安全机制的二次验证。

申请企业体验号:

企业号顾名思义就是企业来申请的号,申请时就像申请服务号一样,需要提供各种组织证明文件,对广大开发者来说很难操作,好在腾讯公司也像服务号一样开通了体验号申请,留意企业体验号的有效期间非常短,只有90天(服务号测试账号有1年有效期),且如果企业体验号长期不使用还会收到腾讯公司的提前失效提醒邮件。企业体验号的申请链接如下,开发者只需要按照腾讯公司的引导完成注册步骤,立刻就能获得体验号:

http://qydev.weixin.qq.com/try?t=experience

通讯录添加成员:

与公众号不同的是,因为是面向企业内部,所以腾讯允许企业主动添加粉丝,具体操作是进入到通讯录后点击+按钮添加新成员,留意作为唯一识别个人信息,微信号、手机号或者邮箱必须至少有一个,直接搜集微信号通常比较困难,一般可以使用企业HR数据库里的手机号和邮箱等信息,具体操作上除了手工添加还可以通过Excel模板导入以及通过腾讯企业号微信API来添加,关于API添加用户稍后章节介绍。


页面名称是EmployeeAuth,页面代码如下,有些属于apex代码特有的标签,无需做深入理解,重要是在第13行按钮的action属性指定了bind方法,当点击按钮的时候将调用控制器类EmployeeAuthController的bind方法:


  
  

Please input your user name and password

UserName: user
Password: 123


UserName:

Password:  

{!msg}

在解读EmployeeAuthController控制器类的代码前我们首先看看微信二次认证的步骤。

二次验证的步骤与机理:

1. 首先,当微信一次验证(或邮箱或手机号码等认证)完成后,微信会发送如下图所示的消息给到用户:

二次验证的代码实现:

按照前面的思路,我们首先获取从腾讯跳转过来的code,并通过code换取用户的userid,换取的这个过程在页面加载中完成,为此主要代码应放在类构造器里。下面的代码里设置了五个变量,其中strPassword和strUsername和用户在页面里输入的用户名和密码相对应,userID用来存储换回来的userid信息,msg用来调试帮助在页面里显示中间信息,accessToken则用来存储access token:

 public class EmployeeAuthController {

    public String strPassword { get; set; } 
    public String strUsername { get; set; }  
    public String msg { get; set; } 
    public String userID { get; set; } 
    public String accessToken { get; set; } 

    public EmployeeAuthController (){  
        accessToken = obtainAccessToken(); 
        String code = ApexPages.currentPage().getParameters().get('code'); 
        //Obtain user ID 
         Http h = new Http(); 
         HttpRequest req = new HttpRequest(); 
         req.setMethod('GET'); 
         req.setHeader('Accept-Encoding','gzip,deflate'); 
         req.setHeader('Content-Type','text/xml;charset=UTF-8'); 
         req.setHeader('User-Agent','Jakarta Commons-HttpClient/3.1');  
         req.setEndpoint('https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=' + accessToken + '&code=' + code + '&agentid=0'); 
         String bodyRes = ''; 
         try{ 
            HttpResponse res = h.send(req); 
            bodyRes = res.getBody(); 
         } 
         catch(System.CalloutException e) { 
            System.debug('Callout error: '+ e); 
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, e.getMessage())); 
         }    
         msg = bodyRes ; 
         //String operation to obtain userID: 
         JSONParser parser = JSON.createParser(bodyRes); 
         while(parser.nextToken() != null){ 
             if((parser.getCurrentToken() == JSONToken.FIELD_NAME)){ 
                 String fieldName = parser.getText(); 
                 parser.nextToken(); 
                 if(fieldName == 'UserId'){ 
                     userID = parser.getText(); 
                 } 
             } 
         } 
         msg = userID; 
    }

}

上述代码第9行调用obtainAccessToken方法获取accessToken,后续会介绍该方法的详情,accessToken两个小时内会失效,所以这里采取实时获取的方式,当然可以设计的再巧妙些以省却每次实时获取accessToken的网络开销。第10行获得了从腾讯跳转过来时带的code参数,从第11行通过HttpRequest方法来调用换取接口获得userid,留意第18行指定了agentid为0,这是因为验证消息是从企业小助手应用发起的,而企业小助手应用id是0。第29行开始解析返回来的JSON数据获取userid。

下面是obtainAccessToken方法,方法内容也比较直接,主要通过调用gettoken接口来获取accessToken,并通过JSONParser类来解析返回的JSON数据以获得accessToken:

 private String obtainAccessToken(){ 
        String token; 
         Http h = new Http(); 
         HttpRequest req = new HttpRequest(); 
         req.setMethod('GET'); 
         req.setHeader('Accept-Encoding','gzip,deflate'); 
         req.setHeader('Content-Type','text/xml;charset=UTF-8'); 
         req.setHeader('User-Agent','Jakarta Commons-HttpClient/3.1'); 
         req.setEndpoint('https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=wx548178d7f347f582&corpsecret=9pwWy0AVoT6V65hnwZLYdi4jnLLx65ofBRb_Ds0mAozysQoywDaqbqYCqglm2vhr'); 
         String bodyRes = ''; 
         try{ 
            HttpResponse res = h.send(req); 
            bodyRes = res.getBody(); 
         } 
         catch(System.CalloutException e) { 
            System.debug('Callout error: '+ e); 
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, e.getMessage())); 
         }    
         msg = bodyRes; 
         JSONParser parser = JSON.createParser(bodyRes); 
         while(parser.nextToken() != null){ 
             if((parser.getCurrentToken() == JSONToken.FIELD_NAME)){ 
                 String fieldName = parser.getText(); 
                 parser.nextToken(); 
                 if(fieldName == 'access_token'){ 
                     token= parser.getText(); 
                 } 
             } 
         } 
         msg = token; 
         return token; 
    }

接下来最重要的方法是bind方法,该方法将负责用户身份验证以及通知腾讯用户关注成功,可以看到下面代码里第2行到第6行只做了很简单的用户名密码校验,真实场景里可以根据企业的具体认证机制进行替换,从第9行开始也即企业内部用户认证通过后开始调用authsucc接口通知腾讯用户关注成功。

 public PageReference bind() {  
        if(!strUsername.equals('user')){ 
            msg = 'Please input correct user name';  
        } 
        else if(!strPassword.equals('123')){ 
            msg = 'Please input correct password';  
        } 
        else{ 
            msg = 'Bind successfully!'; 
            //Notify tencent to add user 
            Http h = new Http(); 
            HttpRequest req = new HttpRequest(); 
            req.setMethod('GET'); 
            req.setHeader('Accept-Encoding','gzip,deflate'); 
            req.setHeader('Content-Type','text/xml;charset=UTF-8'); 
            req.setHeader('User-Agent','Jakarta Commons-HttpClient/3.1'); 
            req.setEndpoint('https://qyapi.weixin.qq.com/cgi-bin/user/authsucc?access_token=' + accessToken + '&userid=' + userID); 
            String bodyRes = ''; 
             try{ 
                HttpResponse res = h.send(req); 
                bodyRes = res.getBody(); 
             } 
             catch(System.CalloutException e) { 
                System.debug('Callout error: '+ e); 
                ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, e.getMessage())); 
             }    
             msg = bodyRes ;  
               } 
    }

更多Force.com微信企业号开发系列- 启用二次验证相关文章请关注PHP中文网!

推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 大连微软技术社区举办《.net core始于足下》活动,获得微软赛百味和易迪斯的赞助
    九月十五日,大连微软技术社区举办了《.net core始于足下》活动,共有51人报名参加,实际到场人数为43人,还有一位专程从北京赶来的同学。活动得到了微软赛百味和易迪斯的赞助,场地也由易迪斯提供。活动中大家积极交流,取得了非常成功的效果。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
author-avatar
奋斗中DU_536
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有