Web网站扫【小程序码】登录的技术实现!记得收藏,要用时别找不到!

语言: CN / TW / HK

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。


前言

我准备给彩虹屁老婆插件开发一个皮肤/模型下载网站,里面需要具备用户系统。但我又得去完整开发一套注册,用户激活机制。

image.png

不过当时我的第一反应是可以利用微信公众号的扫码登录,但公众号的扫码登录接口必须得是服务号才可以使用。服务号的注册又必须使用营业执照走企业认证,总之比较麻烦。恰好当时我的小程序猿创聚合助手已经发布了,所以我就在思考,能否直接利用小程序码的接口来自己设计一套扫码登录流程呢?

如何实现

经过一番思考和调研,我确定以下方式是可行的

利用生成小程序码的接口wxacode.getUnlimited,我们可以生成无限个数的小程序码,虽然该接口携带参数有些限制,但不影响整个逻辑的实现。

扫小程序码登录逻辑如下:

未命名.001.jpeg

核心技术点

生成时间戳签名

Web端生成的时间戳签名必须得是唯一的,如果出现不唯一的签名,用户登录就会乱套了。而生成小程序码所使用的getUnlimited接口仅允许携带一个scene参数,长度要求为32个字符以内。

保证唯一性有很多GUID/UUID的方案,但在本例里,小程序码携带参数的字符数量是有限制的,所以常见方案都不太适合。我最后找到的是nanoid这个方案,非常符合我的需求。

image.png

~~~javascript /* 一个小巧、安全、URL友好、唯一的 JavaScript 字符串ID生成器。

“一个惊人的无意义的完美主义水平, 这简直让人无法不敬佩。”

小巧.  130 bytes (已压缩和 gzipped)。 没有依赖。 Size Limit 控制大小。 快速.  它比 UUID 快 60%。 安全.  它使用加密的强随机 API。可在集群中使用。 紧凑.  它使用比 UUID(A-Za-z0-9_-)更大的字母表。 因此,ID 大小从36个符号减少到21个符号。 易用.  Nano ID 已被移植到 19种编程语言。 */

import { nanoid } from 'nanoid' model.id = nanoid() //=> "V1StGXR8_Z5jdHi6B-myT" ~~~

生成小程序码

这里需要注意的是,我们在web端里通过调用生成小程码的接口,将最终的小程序码显示在网页里。scene是一个不可变的参数名,参数内容里放的是时间戳签名。

~~~javascript async function getWXACodeUnlimited(scene,page){ const access_token = await getAccessToken(); const res = await uniCloud.httpclient.request("http://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+access_token,{ method:"POST", headers:{ "Content-Type":"application/json" }, data:{ scene:scene, page:page } });

return res.data;

} ~~~

  • 扫描小程序码获取签名

使用微信扫描小程序码后,会进入到小程序并打开指定的page(小程序内页面),在该页面的onLoad事件中可以拿到scene参数。

~~~javascript onLoad(options) { var scene = options.scene; var loginToken;

if(scene){
  loginToken = scene;
}

wx.login({
    success: (res) => {
        cloudApi.callFunction({
            name:"users",
            data:{
                action:"login",
                code:res.code,
                logintoken:loginToken
            },
            success: (res) => {

            }
        })
    }
})

} ~~~

上述代码中实现的是,通过login接口获取到code,用于请求code2session接口换取小程序用户的openid,这一步完成,我们等于就在小程序里完成了用户登录。

然后怎么把信息同步给Web端呢?就是这个LoginToken,我这里把它写到与openid相同的用户表数据条目中,然后web端会通过loginToken轮询这个用户数据表,发现匹配数据后返回给Web端,完成Web端的登录

~~~javascript if(loginToken){ await db.collection("users").where({ openid:dbCmd.eq(openid) }).update({ lastlogin:Date.now(), loginToken:dbCmd.set({ value:loginToken, expiretime:Date.now()+6031000000 }) }) } ~~~

现在我们已经完成了扫小程序码登录机制,用户登录网站时,也可以增加小程序的用户和日活跃用户数。

源码

上述所有技术方案的实现,均在《# 🎑提前祝大家中秋快乐,教你做一个【中秋花灯许愿】💖的网站》的案例中可以体验到,源码也在体验网址中。


我叫大帅,一个老程序猿。

让大家开开心心的学习编程是我的理想

感谢掘友的鼓励与支持🌹🌹🌹 - 献给所有技术内容创作者~猿创聚合助手小程序开发难点解析 4赞 - 花60秒给Vue3提的PR,竟然被尤大亲自Merge了~ 161赞 - 产品经理:你能不能用div给我画条龙? 2402赞 - 三种前端实现VR全景看房的方案!说不定哪天就用得上! 2686赞