微信扫码登录二

标签: 无 分类: 未分类 创建时间:2021-07-28 07:06:21 更新时间:2025-04-28 14:37:41

在上一篇文章 (微信扫码登录) 中,我写了两种扫码登录方式,因为刚开始学习,所以很多不了解,这一篇是在尝试了扫码登录之后,又回过头来进行了总结,并且结合了自己的实例进行了一篇重复性的说明。

1.开放平台方式

开放平台的二维码登录,需要在开放平台中定义相关的应用,上传相关资料后进行审核,审核通过后就可以使用其开放的能力了。登录微信开放平台地址:https://open.weixin.qq.com/ ,点击管理中心->网站应用,可以创建网站应用,也可以创建移动应用。如下图的示例:

创建完相应的应用之后,可以直接构造相应的二维码扫描页面,如浏览器打开地址:https://open.weixin.qq.com/connect/qrconnect?appid=xxx&redirect_uri=xxx&response_type=code&scope=snsapi_login&state=xxx#wechat_redirect 就会直接显示二维码扫描页面。扫描后,页面会直接跳转到 redirect_uri 参数定义的地址上,并且带上code和state参数。至于进一步的获取用户权限,进行比对,可以根据官方的说明:微信登录功能 /网站应用微信登录开发指南 获取access_token,openid等信息,然后自行进行数据权限认证。

2.公众号方式

使用公众号登录的方式,不需要在开放平台中新建应用,但是要实现像开放平台那样的功能,手机扫描pc端的二维码,然后使pc端跳转到一个页面,也是比较麻烦的。

(1) pc端需要使用第三方插件将 授权url地址加上 tempcode (参数名称自定义) 字符串,转换成二维码供用户手机扫描。并且定时轮询后台接口是否扫码授权成功,如果授权成功,还需要进行跳转.
(2) 服务端主要提供的就是授权接口,以及获取用户授权信息之后,将信息临时以参数 tempcode 为标志,保存在内存中,并跳转到显示登录成功的页面。同时还应该提供 tempcode 参数查询是否登录的接口。
(3) 手机端主要就是借助微信,扫描pc端的二维码,然后微信会自动跳转到定义的授权接口,授权接口只需要返回一个html页面,标志用户扫描成功就可以了,最好这个页面是可以自动关闭的。

(1) 创建静态二维码
这一步,主要是在PC端页面,使用qrcode.js 库,这样的二维码生成库,将一串url地址变成一个二维码,这里我用 /index?tempcode=xxx 这个接口代替好了。

(2) 发起授权请求
在 index 这个接口中,需要通过微信提供的 authorize 这个接口,传入相关的 app_id 等信息,构建授权信息请求。

1
2
3
4
5
String app_grantscope="snsapi_userinfo";
String url= "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + app_id + "&redirect_uri="
+ URLEncoder.encode("http://"+domain+"/"+projectName+"/get_auth_access_token?urlcoding="+urlcoding+"&"+query, "UTF-8") +
"&response_type=code&scope="+ app_grantscope + "&state=xxx#wechat_redirect";
response.sendRedirect(url);

微信扫描上面生成的二维码后,就会直接跳转到 index 这个接口中,然后执行上面的代码,最后会跳转到 redirect_uri 上,并且带上 code和state。上面的代码中,就是跳转到了 “/get_auth_access_token” 这个接口中,并且还附带了我自己定义的一些参数,比如上面的query参数,以及tempcode参数等。

(3) 保存用户信息
在 get_auth_access_token 这个接口中,程序就可以拿到临时code,构造请求地址:```https://api.weixin.qq.com/sns/oauth2/access_token? appid=app_id&secret=app_secret &code= code&grant_type=authorization_code`` 去获取该授权用户的unionid和openid,以及调用的权限的access_token,进一步根据这个 accesss_token,可以获取其他的权限接口信息。获取到用户的openid和unionid之后,可以自行进行权限认证或者是其他的操作,比如可以根据openid比对WxUser表的主键 WxOpenid,是否存在,确定是否给予该用户相应的权限。

为了更加接近于扫码登录,其实我在获取到授权之后,进一步让用户的【手机端】,也就是get_auth_access_token 这个接口,跳转到了一个名为/scan的页面。这个页面的作用就是显示一个扫码成功的信息,并且在五秒后自动关闭自己,这样用户的手机微信页面就回到了信息列表了,看起来就好像扫码成功了一样,如果这个页面不自行关闭,其实也是完成了授权过程,只不过看起来不直观。

tempcode参数的意义,是为了标志用户是否扫码登录的关键。我会根据这个tempcode,将用户扫码后的信息,以及权限比对(主要是数据用户是否有权限查看该数据库)信息保存在缓存中。

(4) 轮询是否授权
在PC端生成二维码的同时,我会有另外的接口 /user/checkloginByCode,查询用户是否扫码登录过了。使用定时轮询的方式,每隔5秒钟,调用该接口,通过传递参数tempcode,也就是上面的 tempcode=xxx ,查看服务器内存中是否已经存在了 xxx 这个临时码的数据,因为有了这个数据,就表明用户已经扫描过了,已经授权过了,没有授权的用户,是无法在内存中生成这个 tempcode 临时码对应的数据的。根据这个特性,这个临时码应该是全局唯一的,并且有时效性,被验证过之后,内存中应该即刻销毁,不再有效。当我获取到了用户的信息之后,就可以让pc端进行跳转了,必要时pc端还需要自行保存用户信息。

也可以用长连接或者是websocket,微信开放平台的二维码扫码登录就是用的长连接的方法,暂时我这里用了轮询的方法,简单方便,但是对服务器压力较大。

(5) 登录后跳转
当使用轮询查询接口 /user/checkloginByCode 返回了用户登录信息之后,就可以在PC端进行跳转了,整个过程也就结束了。

缺点
我突然发现了这种模式的缺点,加入checkloginByCode返回了用户的权限信息,或者是一个token,是不是任何一个人只要是构建了这么一个二维码,让用户扫描了,都可以获取到用户的信息了呢?这样的情况该如何避免呢?

  • 接口全部使用https,不允许非法请求
  • 关于这个tempcode的生成,可以让服务端生成,类似于解决跨站请求伪造的方法
  • 验证HTTP Referer字段
  • 提示用户不要扫描非法的二维码

3.共同点

(1)无论使用微信公众号方式进行扫码登录,还是使用开放平台扫码登录方式,都需要根据临时code,换取用户的openid或者是unionid,或者是access_token。
(2)获取到openid之后,还需要进行二次权限的认证,以保证该用户是否有进入该数据库的权限,或者是进入到哪一个数据的权限,目前主要就是和WxUser用户表中的主键WxOpenid进行比对,获取用户的权限信息。

小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。