微信扫码登录

标签: 无 分类: 未分类 创建时间:2020-07-06 03:08:42 更新时间:2025-04-28 14:37:41

微信的扫码登录,有两种实现思路
(1) 第一种是微信开放平台的授权方式,用户扫描pc端的二维码,pc端网页就会跳转到相应的地址上去,手机端会跳出授权页面,授权之后,网页上会跳到相应的页面,手机微信端就会直接关闭页面,跳到普通的聊天记录页面。

这种方式是官方已经提供了可以进行跳转的url,只需要页面网站打开这个链接,就可以直接生成一个二维码。

第三方使用网站应用授权登录前请注意已获取相应网页授权作用域(scope=snsapi_login),则可以通过在PC端打开以下链接: https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect 若提示“该链接无法访问”,请检查参数是否填写错误,如redirect_uri的域名与审核时填写的授权域名不一致或scope不为snsapi_login。

(2) 第二种,其实就是用在微信公众号上,用户扫码之后,手机端微信公众号会跳到相应的页面引导用户授权,电脑上不会有什么动作,或者说本身扫码的就是一张静态的贴在桌子上或者是墙上的微信二维码图片。

参考文章:
1.TikTok二面: 说下二维码登录的原理? (这个是使用二维码登录的一个原理的讲解,其实大体上和微信扫码登录差不多,生成token,轮询验证是否扫码登录成功)
2.网站应用微信登录开发指南 微信官方关于授权认证的说明

注意
微信开放平台和微信公众号是两个不同的体系。

微信公众号(公众平台) 和 微信开放平台 是两码事。公众号(公众平台)获取的scope只包括两种:snsapi_base 和snsapi_userinfo,前者是静默获取,用户无感知;后者是需要用户确认同意的。
但是微信开放平台(https://open.weixin.qq.com/) 就可以获取snsapi_login这种scope。坑爹的是,公众平台的认证和开放平台的认证是独立的,你如果想获取snsapi_login,还需要重新注册开放平台,交300块钱认证。
如果你只是想实现微信扫二维码登录的话,其实snsapi_base 也足够了,因为它可以获取到用户的openid,你可以之后用来和自己数据库中作比对。

还有参考文章7中有人这样说:

微信公众号(公众平台) 和 微信开放平台 是两码事。公众号(公众平台)获取的scope只包括两种:snsapi_base 和snsapi_userinfo,前者是静默获取,用户无感知;后者是需要用户确认同意的。
但是微信开放平台(https://open.weixin.qq.com/) 就可以获取snsapi_login这种scope。坑爹的是,公众平台的认证和开放平台的认证是独立的,你如果想获取snsapi_login,还需要重新注册开放平台,交300块钱认证。
如果你只是想实现微信扫二维码登录的话,其实 snsapi_base 也足够了,因为它可以获取到用户的openid,你可以之后用来和自己数据库中作比对。

我的理解,其实snsapi_login这个权限,当你在开放平台注册了一个网站应用的时候,自然就会拥有了,不用再其他的地方继续申请相应的权限了。

1.开放平台

使用官方提供的生成二维码的链接,直接生成二维码,扫码二维码之后,会通过redirect_uri直接跳转到相应的页面。(这种适用于微信开放平台)

1
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

参数说明:

参数 是否必须 说明
appid 应用唯一标识
redirect_uri 请使用urlEncode对链接进行处理
response_type 填code
scope 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可
state 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验

注意
1.scope是:snsapi_login
2.其中的appid需要登录微信开发者平台,然后点击网站应用

然后打开应用的详情,查看appid和AppSecret

这种授权模式,比较受限制,就是二维码网页已经生成好了,就是黑底加上白色的二维码,如果我想实现其他的背景,或者是自定义二维码的大小,就需要另外的方法。这里参考文章3的官方文档中,也说明了如何内嵌应用,需要借助于wxLogin.js代码。

参考文章:
1.移动应用微信登录开放指南
2.内嵌式js微信扫码登录及自定义样式 (这个是如何实现自定义的微信扫码认证授权的模式)
3.网站应用微信登录开发指南 (官网生成二维码的方式说明,讲了两种生成方式,一种qrconnect方式,一种是wxLogin.js方式)

2.公众平台

第二种扫码登录,要想实现第一种网页扫码登录,然后pc端跳转到相应的页面,其实有点绕弯了,使用了公众号网页授权的模式。

这种模式适合于公众号这种,而没有开通公众开放平台,就好像我们在微信公众号上的第三方网站一样。不使用官方提供的二维码生成链接,而是利用了使用微信扫一扫,如果扫出的二维码是一个网址,那么微信就会自动跳到这个网址上。于是我们就可以使用QRCode这种前端生成二维码的插件,将后端进行网页认证的函数进行二维码化,我们扫描这个二维码,回调到授权页,授权成功后,将这个网页(微信端)关闭。然后我们写一个函数(pc端),不断的轮询后台,是否已经认证过了,如果认证过了(即获取到了微信用户的openID和unionID),那么就进行跳转(pc端)。如下代码(pc端)所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 进行登录
var baseUrl="http://test.com";
var randomId = parseFloat(Math.random()*89999999+1000000).toFixed(0);
// 扫码后跳转的页面
var strLink = "http://test.com/wechatBridge?url=http://test.com/web/scan?randomId="+randomId;
var canvas = document.getElementById('code');
new QRCode(canvas, {
text:strLink,
width:200,
height:200,
});
// 定时调用获取登录状态
setInterval(function(){
var url="/getOpenidAndUnionidAndTokenByRandomId"
$.ajax({
url:baseUrl+url,
type:"post",
data:{
randomId:randomId
},
success:function(data){
data=JSON.parse(data);
if(data&&data.status==200){
var result=data.data;

Cookies.set('token', result.token, { expires: 1 });
Cookies.set('openid', result.openid, { expires: 1 });
Cookies.set('unionid', result.unionid, { expires: 1 });

//页面跳转
// location.href="./dblist.html";
location.href="./index.html";
}
},
error:function(text){
console.log(text);
}
})
},2000);

其中test.com/wechatBridge中进行http请求的构造:https://open.weixin.qq.com/connect/oauth2/authorize,然后获取临时code,通过临时code获取access_token,然后再通过access_token获取用户信息。可以参考微信网页开发-网页授权进行实现,这里有一点需要注意就是网页授权的域名,只有两个,如果多于两个域名要用没可能就需要通过桥接的方式进行了。

关于网页授权access_token和普通access_token的区别:
1、微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息;
2、其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。

参考文章:
1.解决微信授权回调页面域名只能设置一个的问题 (这是使用php进行开发的,但是原理应该说的比较明白了,就是使用一个代理)
2.多个域名获取微信登录授权权限

3.扫码后自动关闭

当使用公众平台进行页面扫码登录后,为了不给用户造成实质性的影响,最好就是扫码登录后,微信上关闭这个页面,也就是实现微信上扫码一个页面,最后会跳转到这个页面,过两秒中之后关闭这个页面,回到微信的聊天列表中。

于是我在代码中尝试添加了WeixinJSBridge 对象的判断,结果还是不起作用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script type="text/javascript">
// 两秒之后关闭页面
window.onload=function(){
// 如果是微信浏览器
if(typeof(WeixinJSBridge)!="undefined"){
setTimeout(function(){
//这个可以关闭安卓系统的手机
document.addEventListener('WeixinJSBridgeReady', function(){ WeixinJSBridge.call('closeWindow'); }, false);
//这个可以关闭ios系统的手机
WeixinJSBridge.call('closeWindow');
}, 2000)
}
setTimeout(function (){
window.close();
},2000)
}
</script>

经过修改和测试,微信上可能不支持window.onload函数,最后的代码如下,放到body后面执行,而且也很奇怪使用typeof(WeixinJSBridge)方法,alert返回竟然是undefined。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script type="text/javascript">
// 关闭网站
// alert(typeof(WeixinJSBridge)); 输出undifined
setTimeout(function(){
// 原生浏览器
window.close();

// 微信浏览器
document.addEventListener('WeixinJSBridgeReady', function(){
WeixinJSBridge.invoke('closeWindow',{},function(res){});
}, false);
WeixinJSBridge.invoke('closeWindow',{},function(res){});
}, 3000);
</script>
参考文章:
1.微信浏览器关闭 (这里开篇就是结束了一种通过不同浏览器判断windows.clouse失效的问题,最后就是使用使用WeixinJSBridge的文章)
2.js里面windows.onload函数不执行 (onload函数)
3.微信内置浏览器私有接口WeixinJSBridge介绍 (这个也说了有使用WeixinJSBridge进行页面关闭的操作)
5.Weixin JSAPI (这个是官方的JSAPI调用说明,这里也有closeWindow,但是使用的是invoke执行)
6.微信内置浏览器私有接口WeixinJSBridge介绍 (这篇文章也是调用的call,但是不起作用)
7.如何通过js关闭微信浏览器页面 (这里除了写WeixinJSBridge.call(‘closeWindow’);还有使用微信JS-SDK进行调用的wx.closeWindow();方法)
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 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.
幸福是年华的沉淀,微笑是寂寞的悲伤。