0%

微信扫一扫登录

个人网站是无法接入微信扫一扫登录的,只能使用曲线救国的方式,采用小程序了,小程序是可以获取到微信用户的 UnionID 的。

首先第一步要注册一个小程序应用,很简单的,用邮箱申请即可,点击注册

注册完成之后就可以进行开发了,我后台服务使用的是node来写的

生成小程序二维码

要做扫一扫登录,二维码是不可少的,官方也提供了几种生成二维码的方式。查看生成方式

我使用的是A接口,详细信息可查看官方文档。

1
POST https://api.weixin.qq.com/wxa/getwxacode?access_token=ACCESS_TOKEN

从api上可以看出,调用这个接口需要传入成一个 ACCESS_TOKEN ,这个不是我们生成的,需要调用小程序的服务来获取到。

ACCESS_TOKEN

获取 ACCESS_TOKEN 示例

1
2
3
4
5
6
7
8
9
10
11
12
const getWeChatAccessToken = () => {
return new Promise((resolve, reject) => {
let url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appId}&secret=${secretKey}`
axios.get(url).then(res => {
resolve(res.data)
}).catch(e => {
errorlog.error(e)
resolve(Common.unifyResponse("获取微信token失败", 500))
})
}
})
}

token过期的时间是由微信服务控制的,拿到之后可以存到redis中,不需要每次都去获取新的

获取到token之后就可以调用生成二维码的方法了

调用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 const getQRCode = (access_token) => {
return new Promise((resolve, reject) => {
let fileName = Common.randomNumber()
let url = `https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=${access_token}`
axios.request({
method: 'post',
responseType: 'arraybuffer',
url,
data: {
path: 'pages/login/login?clientId='+fileName
}
}).then(res => {
fs.writeFile(Common.config("qrCode") + fileName + ".jpeg", res.data, "binary", function (err) {
resolve(fileName)
});
}).catch(e => {
errorlog.error(e)
resolve(Common.unifyResponse("获取二维码失败", 500))
})
})
}

返回的是二维码的文件名称

1
2
3
4
5
6
7
8
9
10
11
  LoginRouter.post("/qrlogin/:clientId", (req, res) => {
let userId = req["userId"];
let clientId = req.params.clientId
let token = makeToken(userId);
axios.post(apiConfig.socketUrl, {
clientId,
message: token
})
res.send(true)

})

处理登录请求,在小程序完成授权之后,调用webSocket服务通知页面授权成功,跳转到首页

页面显示二维码

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
$.ajax({
url: api,
type: 'get',
success: function (data) {
$('#qrcode').attr("src","/"+data + ".jpeg")
webSocketConnect(data)

}
})

function webSocketConnect(clientId) {
if ('WebSocket' in window) {
ws = new WebSocket(SOCKET_URL + clientId);
} else if ('MozWebSocket' in window) {
ws = new WebSocket(SOCKET_URL + clientId);
} else {
alert("该浏览器不支持websocket");
}
ws.onmessage = function (evt) {
localStorage.setItem("accessToken", evt.data)
window.location.href = 'me.html'

};
}

登录页面调用服务器端生成二维码并显示在页面上,并且连接webSocket服务,等待服务器确认登录。

小程序

login.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
   Page({
onLoad: function (options) {
const scene = decodeURIComponent(options.clientId);
wx.setStorage({
key: "clientId",
data: scene
})
},
login: async function (e) {
let result = await util.getLoginInfo()
if (result) {
let clientId = wx.getStorageSync('clientId')
await util.httpRequest({
method: 'post',
url: 'api/wx/qrlogin/' + clientId
})
wx.switchTab({
url: '../index/index'
})
}
}
})

login.wxml

1
<button open-type="getUserInfo" bindgetuserinfo="login">授权登录</button>