转自:http://www.abyssly.com/2013/09/20/wx_bind/  (原作者的思路蛮清晰的,赞一个!)

最近由于工作需要,接触了微信公众号的开发。业务上要求绑定微信用户和系统用户,以便用户在一次绑定后能够通过系统用户的身份去使用一些功能。我关注的招行信用卡公众号实现了这个功能,所以估计还是可行的,在网上搜索了一下,发现这个问题没什么好的答案,很多都说取不到微信用户名实现不了,甚至有说实现了这个功能的应该是与微信有内部合作的。

搜索无果,遂自己动手实验,后发现其实完全可以的,看来实践才是检验真理的唯一标准,方案上也很简单,我分几点来说。

用OpenID绑定即可

微信接口中虽然没给用户的微信账号,但给了用户的OpenID,这个OpenID对一个公众号是唯一的,测试也证明不会改变,也就是说同一个微信号和同一个公众号交互,我们得到的OpenID是不会变的,因此,可以用OpenID作为微信用户的身份标识。

如何绑定

俗话说,没吃过猪肉还没见过猪跑。看招行信用卡公众号是如何做的,在微信里面给用户一个验证链接,用户点击链接,微信会用内嵌的浏览器打开这个链接,然后就是一般的网页登录验证界面,我们通过HTTP(S)获取用户输入的系统用户名与密码,验证通过后完成绑定。 具体如何生成链接和如何传递OpenID下面详述。

如何生成绑定链接

绑定涉及到用户的身份甚至利益,所以需要注意安全性。我们需要绑定的是OpenID和系统用户,系统用户名是用户直接在链接页面输入后通过HTTP(S)传给我们的,这没有问题。OpenID对用户来说透明,用户不会传给我们,我们也只有在用户在微信中向公众号发消息时才可获得OpenID,所以很明显,OpenID需要包含在生成的链接中,至于需不需要对OpenID作加密就看你自己了,我觉得这不重要,更为重要的是要在链接中带上签名和加上时间戳。因为我们需要确认这个链接是由我们服务端生成的,用户自己或者其他人不能够伪造出这个链接,加上时间戳是为了给这个链接一个过期时间,如果不限制过期时间,假设用户绑定后这个链接通过某种方式被别人知道,那么这个人就可以把自己的账号与用户的微信号绑定。所以我采取的方法是用OpenID、过期时间再加上一个密钥生成签名,生成签名的方法和微信服务器接口验证时的签名方法类似(密钥最好另选一个只有自己知道的)。

如何传递OpenID

有了绑定链接,用户点了绑定链接,但这只是第一步,第二步我们需要在用户在链接页面提交登录请求后进行验证,OpenID怎么传到第二步中呢?有人说了,这还不简单,在登录表单中加一个隐藏域放用户的OpenID一起提交给验证的Handler不就OK了,那我只能说很遗憾,你前面所做的安全工作都白费了,一旦A用户的OpenID泄漏,B用户就可以把自己的账号与A用户的微信号绑定了。所以永远不要相信客户端提交的东西。我的方法是当用户点击生成链接后,在链接页载入时,将OpenID存到session中,因为这个session是没法伪造的(cookie被盗除外),所以只有点击这个链接的用户的session中才会有链接中包含的OpenID。

关于微信服务器签名多说一句

大家都知道微信公众号消息接口验证时微信会向我们服务器发一个GET请求,在其中带上只有我们和微信服务器知道的签名,我们在请求处理Handler中会验证这个签名,这点大家无异议;消息接口验证通过后,微信就会把用户发的消息以POST的方式发给我们,很多人可能会在这里忽视对签名的检查,从而给恶意者伪造用户请求的机会。在微信以POST方式传递用户的消息时,仍然会将签名信息附在URL参数中,我们在处理每一个POST请求时,第一步还是得像处理消息接口验证时一样,去对URL参数中的签名作验证,只有签名验证通过后才可去取POST的信息。

绑定流程的详细描述

我在上面说了基本方法,但不够详细,导致一些新手朋友还是不清楚具体如何操作,所以我在此尝试更加详细地描述整个过程的每一步:

  1. 数据库中建立用户OpenID和系统用户的绑定关系表,初始时为空。

  2. 用户和微信交互时(self:通过点击自定义菜单ClickButton触发),你可以取到用户的OpenID。

  3. 检查数据表,如发现该OpenID没有绑定系统用户,则返回一个链接供用户在微信内嵌浏览器中打开,这个链接打开后类似于系统用户登录界面。

  4. 关键是链接的生成,链接需要带3个url参数:

     1. 用户OpenID:因为你需要在绑定页面中取到是哪个微信用户想要绑定系统用户。2. 时间戳timestamp:这是为了防止链接泄漏出去被恶意利用,具体来说就是一个你指定的过期时间,超过这个时间这个链接就失效了,用户只能再次获取。3. 签名signature:这是为了保证此验证链接只有你才可能生成,用户及第三方均无法伪造。
    
  5. 签名的生成需要你有一个只有你知道的token(密钥,不要与设置在公众号里面的token相同),生成签名方法和验证微信服务器消息真实性类似。流程如下:

     1. 将token、OpenID、timestamp三个参数进行字典序排序。2. 将三个参数字符串拼接成一个字符串进行sha1加密,得到链接的signature参数。
    
  6. 用户打开某个绑定链接时,你首先验证链接的有效性,即按上述5.1和5.2中描述的同样的步骤得到signature与参数中的sinature对比,如果相同,则再检查链接是否超时(self:个人认为,检验是否超时作为第一步更合适,先校验签名比较合适,防止timestamp被恶意篡改),两步验证均通过,你就可以将用户的微信OpenID设置到用户的session中,然后你就可以渲染验证页面(jQuery Mobile),让用户输入其系统用户名和密码以提交给你服务器进行验证。

  7. 在用户提交绑定验证请求后,你只需要检查session中有没有你设置的OpenID,没有自然无效,有的话就是要绑定的OpenID了,此时你可以把这个OpenID从session中删除了。然后你如果验证系统用户名和密码通过后,就把这个OpenID和系统用户绑定起来,加入到第1步中说的绑定关系表中。

  8. 完毕。

PS by self  (个人愚见):这个绑定的思路和微信本身提供的OAuth2.0绑定(参考 http://www.cnblogs.com/txw1958/p/weixin71-oauth20.html)异曲同工,只不过这个banding关系的维护在平台业务方,而不在微信方,在平台业务方维护绑定关系在实际开发中扩展性更好,至少本人选择如斯 :)

微信公众平台 绑定微信用户OpenID与第三方业务账号相关推荐

  1. 微信公众号授权获取用户OpenID和UnionId然后发生消息通知

    微信公众号授权获取用户OpenID和UnionId然后发生消息通知 1.获取微信公众号code 1.微信公众拿取公众号appid和appSecret 2.网页域名授权,这里的域名拼接上html所在位置 ...

  2. 微信公众平台、微信公众平台.小程序、微信.开放平台三者关系及unionid

    以下内容,仅限于根据自己开发以及阅读微信文档总结,错误之处敬请指出,共同进步! 一.微信公众平台.微信公众平台.小程序.微信.开放平台登录地址 项目 微信公众平台 微信公众平台.小程序 微信.开放平台 ...

  3. 微信公众平台与微信开放平台的区别、服务号、订阅号、企业微信的区别

    微信公众平台 vs 微信开放平台 微信公众平台是介绍公众号相关的内容,比如服务号.订阅号.企业微信,所以叫微信公众平台:公众平台也是公众号的管理端,可以编辑推送文章,通常是公众号的运营.开发登录: 微 ...

  4. 微信公众平台推出微信保护提升微信账号安全 附微信保护开启教程

    前两天小美女的微信公众平台要群发消息时提示需要绑定手机才能操作,当时还以为是动态ip的问题,今天微信公众平台安全中心就说升级了,原来那时已经在公测了.微信公众平台推出"微信保护", ...

  5. 微信公众开放平台开发03---百度BAE上搭建属于自己的微信公众平台 -JAVA,微信公众开放平台部署到百度云中BASE2.0,进行调试,木有钱买云服务器的亲们试试

    微信公众开放平台开发03---百度BAE上搭建属于自己的微信公众平台 -JAVA,微信公众开放平台部署到百度云中BASE2.0,进行调试,木有钱买云服务器的亲们试试 技术qq交流群:JavaDream ...

  6. 微信分享开发:准备工作[微信公众平台以及微信中控服务配置](一)

    开发准备工作: ①申请公共号 微信公众平台 ②公共号设置→设置相应的业务域名,JS接口安全域名,网页授权域名(授权登录用) 填写业务域名并把txt文件放到你的项目根目录下 ③,设置ip白名单 到此,配 ...

  7. 百度云搭建微信公众平台服务器,微信大众开放平台开发03-百度BAE上搭建属于自己的微信公众平台 -JAVA,微信公众开放平台部署到百度云中BASE2.0,进行调试,木有钱买云服务器的亲们试试...

    微信公众开放平台开发03---百度BAE上搭建属于自己的微信公众平台 -JAVA,微信公众开放平台部署到百度云中BASE2.0,进行调试,木有钱买云服务器的亲们试试 微信公众开放平台开发03---百度 ...

  8. 微信公众平台—— 获取微信服务器IP地址

    微信公众平台-- 获取微信服务器IP地址 const ServerIpUrl = 'https://api.weixin.qq.com/cgi-bin/getcallbackip?&acces ...

  9. 微信公众平台关于fakeid和openid的解析

    今天在开发项目的时候遇到了个问题: 搞不清楚微信官方接口的fromusername(openid)和公众平台内每个粉丝所拥有的fakeid,于是在测试号中开始了对以上两项的研究,结果如下:   1.对 ...

最新文章

  1. 重磅 | 一场你从未见过的数据中心盛会
  2. 关于初学Go的一些总结
  3. Go Out Otherwise Shut Up
  4. Pycharm上Django的使用 Day8
  5. Redis基础-下载安装配置
  6. Vue Nginx反向代理配置 解决生产环境跨域
  7. 中国邻苯二甲酸二环己酯(DCHP)行业市场供需与战略研究报告
  8. oracle数据库listener开启和关闭trace文件的方法
  9. 12M电信宽带,为什么12台机器上网,总是掉线?有什么办法解决?请给位高手指教...
  10. java路径不存在则创建文件夹_java实现文件夹不存在则创建
  11. H3C DHCP中继实验
  12. 基于SSM的企业人事人员管理系统
  13. 流加密,一次性密码本的原理,简介,事例以及攻击方式
  14. r语言的runmed函数_干旱指数新宠—SPEI的C语言版、R语言版与单独执行软件SPEI Calculator...
  15. flashfxp3.41中文版注册码:(适合最新版本)
  16. Carsim应用:LKA车道保持辅助系统(LQR控制器模型)
  17. PHP 打开文件(txt),写入文件
  18. MathPage.wll not found
  19. 施工现场工地监管如何能够接入4G摄像头实现流媒体服务器视频监控?
  20. 东南亚lazada平台分跨境店和本土店两种,二者的区别都写在这里了

热门文章

  1. VLayout的使用
  2. 差分晶振_LVDS/LVPECL/HCSL/CML模式
  3. 嘉兴培训第二天——第一堂课
  4. ACL20 - Zero-shot Text Classification via Reinforced Self-training
  5. oracle 存储过程插入数据不成功
  6. 堆优化器(Heap-Based Optimizer, HBO)
  7. 欧拉函数(C++ 实现)
  8. 易流科技董事长张景涛接受中国食品安全网专访
  9. S8热销现象背后:三星或赶超苹果
  10. 通用的结构化数据流通工具