nest.js + sms 實現簡訊驗證碼登入

語言: CN / TW / HK

theme: vue-pro

hi, 大家好, 我是徐小夕, 新的一年, 你又博學了嗎?

今天和大家分享一下使用 nodejs 實現簡訊驗證碼登入的方案, 通過對該方案的實現大家可以可以對 nodejs 及其相關生態有一個更深入的理解.

好啦, 話不多說, 我們開始實現.

實現方案

為了更高效的開發 nodejs 應用, 這裡我選擇 nest.js 作為服務端框架, 同時使用騰訊雲的簡訊服務:

具體實現流程如下:

詳細流程如下:

  1. 使用者訪問網站登入頁面, 輸入手機號觸發驗證碼
  2. node伺服器收到請求後, 拼接所需引數(具體在下文會詳細介紹), 請求第三方簡訊服務平臺
  3. 第三方簡訊服務平臺校驗, 通過後下發對應簡訊
  4. 使用者在網站輸入收到的驗證碼, 請求登入介面完成登入

相信大家對第一步沒有太大疑問, 接下來我詳細介紹幾個核心的實現過程.

1. 簡訊服務的配置流程

由於我使用的是騰訊雲的簡訊服務, 所以需要按照約定來完成以下配置:

  • 建立簡訊簽名

傳送簡訊內容時必須帶簽名.

  • 建立簡訊模版

簡訊模版可以讓我們建立自定義的簡訊內容, 還可以建立動態內容, 大家感興趣可以研究一下.

  • 建立應用(一般使用預設即可)

2. nodejs伺服器向簡訊服務平臺發起簡訊呼叫

以上配置完成並稽核通過之後, 我們就可以使用 nodejs 愉快的傳送簡訊了. 這裡我們需要安裝騰訊雲的sdk:

```bash

nest專案中

npm install tencentcloud-sdk-nodejs --save ```

然後在 nest 服務端儲存上一步獲取的:

  • 使用者手機號
  • SmsSdkAppId(應用id)
  • TemplateId(模版id)
  • SignName(簽名內容)
  • TemplateParamSet(需要傳送的驗證碼)

核心程式碼如下: ```js /* * 傳送手機驗證碼 * @param params 請求體 / async registerCode(params: any): Promise { const { phone } = params; if (!phone) { return { code: 400, msg: '手機號為空', }; }

const code = `${rand(1000,9999)}`;
phoneCodeList[phone] = code;

const smsParams = {
  "PhoneNumberSet": [
    `+86${phone}`
  ],
  "SmsSdkAppId": "xxxxx",
  "TemplateId": "12*****",
  "SignName": "dooring服務",
  "TemplateParamSet": [code]
};

try {
  const result = await client.SendSms(smsParams);
  if(result?.SendStatusSet.Code === 'Ok') {
    return {
      code: 200,
      msg: 'Success',
    };
  }else {
    return {
      code: 500,
      msg: `Service error: ${result?.SendStatusSet.Message}`,
    };
  }
}catch(err) {
  return {
    code: 500,
    msg: `Service error: ${err}`
  };
}

} ```

以上是用 nest 寫的一個簡單的 service 邏輯, 主要功能是傳送使用者手機號和簽名引數到第三方簡訊平臺, 下發簡訊. TemplateParamSet欄位為一個數組, 陣列長度取決於我們的簡訊模版中動態變數的配置, 如下:

如果我們配置的模版內容中有2個變數, 那麼TemplateParamSet欄位 的陣列為2項.

3. nodejs實現簡訊驗證碼驗證

最後一步比較簡單. 我們只需要把使用者填寫的驗證碼和我們伺服器生成的驗證碼進行比對即可, 我們可以使用 redis 來快取驗證碼.

最終的實現效果如下:

當然大家可以用自己熟悉的任何 nodejs 框架來實現以上功能(如koa, egg).

更多推薦