注:文章中描述的方案是可以解决问题的方案,但不是最优方案。 改进内容在文章末尾。
扫描微信二维码登录主要有两个目的。一是方便用户,用户可以通过扫描二维码登录,无需记住账户密码;二是方便用户登录。 二是方便开发者通过微信获取用户并进行用户身份认证。 最简单的方法之一就是使用微信开放平台。 但需要缴纳300元认证费。 而如果你已经有微信公众平台,微信公众平台的大部分功能也需要认证才能使用,而这也需要花费300元。 所以对于像我这样已经认证了微信公众平台,又不想花钱认证开放平台的人,我只能想办法不使用开放平台,主要是我穷。 本文主要详细介绍如何基于微信公众平台实现二维码登录,并讲解基于Node.js的技术方案和代码示例。
1.场景
扫码登录的场景很简单,就是用户首先在电脑浏览器中打开登录页面,页面上有一个二维码; 然后用户使用微信扫描页面上的二维码; 然后提示用户登录微信。 如果成功,电脑上的网页会自动跳转到登录后的页面。
2、设计方案
首先熟悉一下微信公众号的几个功能:
基于这些功能,我的解决方案如下:
接下来我们详细介绍一下图中的几个关键点。
2.1. 二维码生成
扫码登录需要先生成二维码。 二维码本质上是一种存储数据的图片介质。 数据可以是 URL 或文本。 可以使用二维码扫描工具扫描出数据。 例如,通过扫描上面设计中的二维码,可以获得一段文字。 那么基于这个原理,我们就可以将URL存储在二维码中。 微信扫码后会自动跳转到该网址。
上面提到微信可以通过授权的URL获取用户的ID,这是第三步中需要的,所以我们的URL需要是授权的URL。
在 Node.js 中生成授权 URL 可以在 - 这个包的帮助下完成。 详细步骤如下:
const OAuth = require('wechat-oauth'); const client = new OAuth('wechat_appid', 'wechat_appsecret'); const url = client.getAuthorizeURL('redirectUrl', 'state', 'scope');
其中 为网页授权回调域名, 为网页授权方法, 为。 这是我们自定义的一个参数。 重定向后会携带该参数,因此一般可以用该参数来代表不同的业务。 更详细的信息请参考微信网页授权。
这样,用户访问该URL后,就会被重定向到上面设置的带有code参数的URL。 第三步,根据代码获取用户。
那么,由于还需要判断是哪个用户登录的,即对应微信和电脑浏览器,所以需要一个唯一的字符串来标识。 即在URL中添加唯一值,以便微信可以知道是哪个客户端(浏览器,即用户)正在登录。
所以我们可以生成一个uuid as。 要生成 uuid,您可以使用 node-uuid 包。 然后我们可以使用 uuid 作为参数来生成授权 URL。
URL 可能如下所示:
const url = client.getAuthorizeURL('http://nodejh.com', '985123a0-7e4f-11e7-9022-fb7190c856e4', 'snsapi_base'); console.log(url); // https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxb8c83c7bd4ac209f&redirect_uri=http%3A%2F%2Fnodejh.com&response_type=code&scope=snsapi_userinfo&state=985123a0-7e4f-11e7-9022-fb7190c856e4#wechat_redirect
最后根据URL生成二维码。 生成二维码最简单的方法是使用 qr- 包。
const fs = require('fs'); const qr = require('qr-image'); const qrSvg = qr.image('I love you!', { type: 'png', ec_level: 'H' }); qrSvg.pipe(fs.createWriteStream('qrcode.png'));
这将在当前目录中生成名为 .png 的二维码图像。 当用户访问登录页面时,将返回图像。
同时还需要做的就是将生成的二维码返回给客户端,因为后面会用到。 您可以将其放入内部或隐藏形式。
2.2 扫描二维码获取
当用户使用微信扫描登录页面的二维码时,会自动跳转到该二维码对应的URL。 例如上例中,会跳转到%3A%2F%&=code&=&=-7e4f-11e7-9022-#。
接下来微信浏览器会继续跳转到回调域名并带上code参数,可能就是跳转后的页面。
所以我们可以从自己后台的参数中获取。
2.3 获取用户
同时URL中还有一个code参数,我们可以根据code获取用户的信息。 您仍然可以使用-。
client.getAccessToken('code', function (err, result) { var accessToken = result.data.access_token; var openid = result.data.openid; });
就是这样。
这里的获取和求和都是在我们自己的服务器上实现的。 微信所做的就是扫码获取二维码中的授权URL,并生成跳转到回调URL的代码。
通过这个我们还可以获得用户信息
client.getUser(openid, function (err, result) { var userInfo = result; });
这时候你可以做一些诸如绑定用户账号之类的事情。 例如,如果数据库中不存在该用户,则存储该用户信息; 如果有用户,可以更新该用户的微信信息,比如微信昵称或者头像,可能已经改变了。
2.4 储存与
有了and,我们还需要存储起来供客户端使用。 它可以存储在数据库或缓存中。
当用户在客户端打开登录页面时,可以将该登录页面带到轮询服务器来判断数据库中是否有对应的登录页面。 如果有,则说明用户已扫描二维码并登录成功; 如果没有,则表示二维码没有被扫描到,继续轮询,直到有数据为止。
2.5 轮询