https://github.com/singcl/xcx_scan_login
微信小程序扫码授权DEMO
https://github.com/singcl/xcx_scan_login
Last synced: 15 days ago
JSON representation
微信小程序扫码授权DEMO
- Host: GitHub
- URL: https://github.com/singcl/xcx_scan_login
- Owner: singcl
- Created: 2022-12-21T08:20:13.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2022-12-21T08:23:24.000Z (over 3 years ago)
- Last Synced: 2025-01-03T13:17:50.272Z (over 1 year ago)
- Language: TypeScript
- Homepage:
- Size: 174 KB
- Stars: 0
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.MD
Awesome Lists containing this project
README
# 微信小程序扫码授权
## 背景
想要使用微信扫码登录自己的网址,通过授权快速获取用户的昵称,头像功能
由于没有企业认证账号,故只能通过微信小程序实现,
## 体验地址
[https://api.nnnnzs.cn/screen-demo.html?env=release](https://api.nnnnzs.cn/screen-demo.html?env=release)
## 源码
[https://github.com/NNNNzs/wechat-screen-tools](https://github.com/NNNNzs/wechat-screen-tools)
## 原理
利用微信小程序的动态创建场景码接口 ([https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html](https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html)),创建短token的信息存储在服务端,而不需要大量信息存储在二维码里,实现授权
## 流程
1. 客户端在请求图片,服务生成 token,注册到认证服务
2. 前端根据 token,获取带场景值的二维码图片,并轮训该 token 状态
3. 使用微信扫码,根据 token 获取应用信息并展示,在小程序授权登录,获取 openid,nickname,avatorImg 等信息
4. 确认允许登录后,发送 confirm 请求,发送 userInfo 值
5. 网络获取到该 token 对应的用户信息
## 流程图

## 核心接口
| 接口 | 传参 | 返回值 | 说明 |
| -------------- | ----------------------- | ------------------ | ------------------------------------------------- |
| getToken | - | token | 获取 token |
| getImgByToken | token | 图片的 arrayBuffer | 获取小程序码 |
| getInfoByToken | token | userInfo | 获取用户信息 |
| status | token | -1\| 0\| 1 | -1 表示为扫码,0 表示已扫码未授权,1 表示已经授权 |
| confirm | nickName、openid,头像等 | - | 小程序的允许授权时确认的接口 |
## 踩坑点
### scene 长度为最大 32 字符,利用 nodejs 的 uuid.v4 生成的值超过 32 位
>解决方案
```js
uuid.v4().replace(/-/g, "").toUpperCase();
```
### 生成二维码时,如果没有指定 page 字段可能会在页面里获取不到场景值(scene)
>解决方案
>指定`page: "pages/index/index"`
### getwxacodeunlimit 接口成功直接返回 buffer 错误返回的是 json,在 axios 中需要根据 response 的 contentType 来判断成功还是失败
> 解决方案
```js
router.get("/getImgByToken", async (req, res) => {
const { access_token, expires_in } = await wechat.getAccessToken();
const ua = req.headers["user-agent"];
const token = req.query.token;
const env = req.query.env;
// env区分 release 发行版本 trial 体验版 develop 开发版
// https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html
axios({
url: "https://api.weixin.qq.com/wxa/getwxacodeunlimit",
method: "post",
params: {
access_token: access_token,
},
responseType: "arraybuffer",
data: {
scene: token,
env_version: env || "trial",
check_path: false,
page: "pages/index/index",
},
}).then((response) => {
const isSuccess = response.headers["content-type"].includes("image");
if (!isSuccess) {
console.log(response.data.toString("utf-8"));
} else {
res.type("png").send(response.data);
}
});
});
```
### 无论是`wx.getUserProfile`还是 `wx.getUserInfo` 无法静默获取 userInfo,都需要授权弹窗登录,不过可以缓存信息
>解决方案
>扫码进入之后onLoad就弹窗,并且存储场景值,允许拒绝授权之后再次
### 开发的时候场景值每次提交代码生成预览版本比较麻烦
>解决方案
>在微信小程序开发工具里面添加条件编译,通过二维码编辑