javaweb实战 微信网页授权——基于测试号开发

(一)开发背景

       一般的网站登录验证这一块的开发,都是使用自己独立的一套的账号体系。问题是显然易见的:用户在每一个网站都要到注册一个新的账户密码。用户就需要耗费脑力众多的网站密码。很多时候,并不是用户密码被盗,而是用户自己忘记了密码。

       这样,微信授权登录的优势就体现出来了。这年代,还有谁不用微信的吗?用户只需要扫码即可登录,带来的便捷性不言而喻。

(二)效果演示

      项目演示地址:http://vps.wiwikiky.top:8080/weixinauth

      项目源码: https://github.com/zhenfeii/weixinauth

(三)原理分析

     官方文档是第一手资料,也是最好的资料。文档开篇即说明:如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。但,这里就有一个问题了。必须是微信客户端直接访问网页,才能获取用户信息。那怎么实现用户pc端网页的授权登录呢?(这里说的有点含糊,但这个问题确是关键!)

    解决思路:pc端网站直接生成二位码,引发用户授权登录。微信客户端确认授权后,会带code参数一起回调开发者自定义的地址。开发者获取到code(已经成功了一半)后,利用code值来调用一系列的接口,即可获取到用户的基本信息:包括openid,nickname,headimgurl.....

(四)开发准备

    (1)  申请测试号:

扫描二维码关注公众号,回复: 6199041 查看本文章

https://open.weixin.qq.com/connect/qrconnect?appid=wx39c379788eb1286a&scope=snsapi_login&redirect_uri=http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

   成功的话,应该能看到这页面

  

    (2)配置回调域名

         a.

          

         b.这里提一下:测试号支持内网ip,比如:192.168.2.123:8080。填写地址的必须是微信客户端能访问的。

        

       

(五)开发

      (1)项目技术栈

       a. java web: 使用原生的servlet + jsp

       b. 数据库: mysql + c3p0连接池

       c. jwt 生成token

       d. HttpSevletResponse操作Cookie

      (2)项目初始化

       项目追求纯粹化,不适用任何框架。c3p0连接池也是自定义的java类。

       可根据个人需求,升级为ssh,ssm均可。

         (3)引导用户同意授权,获取code

         根据官方文档,用户必须在微信客户端访问链接,才有机会获取code。所以我们要引导用户访问某个链接。

          pc端与微信客户端最便捷的交互方式就是二维码。所以,在前端,我们需要生成二维码的js库。这里,我选择“jquery.qrcode.min.js”,一个非常轻量级的库。关键代码:

                

         用户同意授权后,就会跳转到redirect_uri: http://vps.wiwikiky.top:8080/front/weixin/auth。我们就需要设定对应的控制器来的拦截这个请求了。

        

        可以看到,我们可以拿到微信回调的code,以及我们自定义的uuid参数。微信回调,是比较关键的一步,也是比较困难的异步。如果你能成功拦截到微信回调的请求并且获取到code参数,那你就成功了一半了。

      (4)通过code换取access token,通过access token 拉取信息

       到了这里,我们只需要根据官方文档所指引的步骤,调取相对应的api即可。

      在项目里,我对调取api进行了封装。

    

          只需要替换成自己对应APPID,SECRET即可。具体的调用以及业务判断,可参照我的源码。以拿到用户信息为成功标准:openid,等等。

      (5)更新用户信息或新增

         拿到openid(用户唯一标识)后,证明微信客户端授权成功。到了这里,我们可以根据自己项目需求进行对应了。无论基于session验证,还是基于token验证,都是可以的。这里我选择token的验证方式:使用jwt生成token,并存放浏览器的cookie中。每次访问时,都进行token验证。

       具体步骤:获取到openid后,根据openid来对用户表进行查询。如果用户存在,则更新hash,生成token;如果用户不存在,这插入用户信息。这里,吃瓜群众可能会对hash值有疑问了,hash值有什么作用?这里的hash值就是保证用户单点登录。举个例子,如果用户使用chrome浏览器登录后,再使用360浏览器登录,那么Chrome浏览的token就非法了。相当于chrome浏览器被迫下线的效果。

      这里可以展示下用户表:

     

     (6)token的生成与解析

     初学者刚学习jwt(java web token)时,会感觉jwt非常高大上,以及无从下手。但是java中有相对的包,使用非常方便。

     直接上代码:

       说白一点:token就是带有信息、加密过的字符串。因为我们使用了私钥,除非别人知道了秘钥,否则无法破解。token能加密,也可解密。解密后,我们就可取回相对的信息了

      我们可以看到:可以把我们的需要存储的信息封装到Map对象,再生成token; 也可以解析token得到我们的想要的信息。

     

     在这里,我们只封装openid,hash,timestamp。

    各自的作用: 

        openid:验证用户身份;

        hash: 单点登录;

        timestamp: 设置token的有效期

     (7)使用Filter过滤器进行权限认证

      具体步骤:

        拦截/admin/*路线下的所有请求,取出cookie中token。

        若token不存在,不放行,重定向到登录页面。

        若token存在,分别对openid,hash,timestamp进行校验,都合法,则放行;否则,重定向到登录页面。

        另外,我们还可以取出请求路径,作为参数附带到登录页面。但登录成功后,可直接跳转到原来页面。

    (六)难点突破

      我们先用流程图来回顾整个授权过程。

       这里的难点就是:微信授权后,服务器怎么通知pc客户端?

       这里的解决方案是:使用ajax轮询。pc生成二维码前,随机生成一个uuid,作为该窗口的临时标识。授权后,服务器根据uuid找到对应的窗口。具体实现,如下:

      (1)请求生成时,就生成一个唯一标识,并存储在全局变量中

        (2)前台生成二维码时,附带上该参数

      (3)微信后调后,再取出改参数。确认是哪个窗口的验证。

     (4)授权后,打上对应uuid成功授权的标识

     (5)ajax轮询中,根据uuid,找到uuid是否授权的标识

       js代码:

      至此,微信网页授权大功告成。具体请参考源码。

  (七)注意:

      源码运行需要修改的地方:

       a. 初始化用户表,源码中有相对的sql;修改db.properties文件,对应username,password

       b. WeixinAuthUtils.java 修改成自己的APPID,SECRET

       c. weixinlogin.jsp文件中生成二维码对应的字段改为自己定义的回调地址(与配置回调域名相对应上)。

  (八)总结

       想做微信授权登录已经很久了,最开始是看到慕课网中spring boot开发饿了么项目时做的这个功能,但人家用的是正式号来做的,省了很多功夫。后来听说测试号也可以做,自己就看着网上的博客,跟官方文档来做。结果,获取code就折腾三四天,而且当时权限验证这一块,具体实现流程不清楚。于是,就一直拖着。

      最近有功夫,再把官方文档消化了一遍。终于有了头绪。不得不说,官方文档是学习的第一手资料啊。

参考资料:

(1)官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842

猜你喜欢

转载自blog.csdn.net/weixin_39454194/article/details/83892875