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("https://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贊