欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

微信小程序常見的兩種登錄方式詳解

 更新時間:2024年05月04日 10:20:33   作者:零一行者  
這篇文章主要介紹了微信小程序常見的兩種登錄方式,一種基于手機號碼進行登錄,另一種是使用用戶在公眾號下的唯一標識進行登錄,需要的朋友可以參考下

小程序登錄

小程序有兩種登錄方式,一種基于手機號碼進行登錄,另一種是使用用戶在公眾號下的唯一標識(openid)進行登錄(小程序是公眾號的一種).

接下來先講解下,基于 openid 登錄。

基于openid登錄

先看下圖,描述通過微信小程序提供的 code 換取當前用戶在小程序中的唯一標識,詳細流程可以參數(shù)下圖:

接下來通過代碼實現(xiàn)下大概流程:

獲取 code

uni.login({
  success: async (res) => {
    if (res.errMsg === 'login:ok') {
      const { data } = await login({
        code: res.code,
      });
      // 保存用戶信息
    }
  },
  fail(e) {
    uni.showToast({
      title: e.message,
    });
  },
});

服務端接收 code 去微信后臺換取對應 openid

// nodejs 部分代碼
const { appid, secret, grant_type } = require('../config/wx');
router.post('/login', (req, res) => {
  const { code } = req.query;
  const { appid, secret, grant_type } = require('../config/wx');
  const { openid } = await request.get('/sns/jscode2session', {
    appid,
    secret,
    js_code: code,
    grant_type,
  });
});

在數(shù)據(jù)庫中查找對應 openid 是否存在

const { appid, secret, grant_type } = require('../config/wx');
router.post('/login', (req, res) => {
  // 1. 獲取 code
  const { code } = req.query;
  // 2. 通過 code 獲取 openid 和 session_key
  const { openid } = await request.get('/sns/jscode2session', {
    appid,
    secret,
    js_code: code,
    grant_type,
  });
  // 3. 查找用戶是否已經(jīng)注冊
  models.user
    .findOne({
      where: {
        openid,
      },
    })
    .then((user) => {
      if (user) {
        // 3.2 如果用戶已經(jīng)注冊,返回用戶信息
        res.json(
          new Result({
            data: user,
            msg: '登錄成功',
          })
        );
      } else {
        // 3.3 如果用戶沒有注冊,創(chuàng)建用戶并返回用戶信息
        const username = randomUserName();
        models.user
          .create({
            nickname: username,
            openid,
            avatar: '/uploads/default-avatar.png',
          })
          .then((user) => {
            res.json(
              new Result({
                data: user,
                msg: '登錄成功',
              })
            );
          });
      }
    });
});

上面就是一個基于 code 獲取 openid,并通過 openid 創(chuàng)建新的用戶,并將創(chuàng)建好的用戶返回。

為了方便理解,這里簡化描述了登錄邏輯。在實際業(yè)務代碼中,通常會使用 openid 、 session key 和用戶信息來創(chuàng)建自定義登錄憑證(token),并在登錄時將用戶信息和 token 一起返回給前端。前端會將 token 存儲在本地,并在下一次需要登錄的業(yè)務請求中攜帶 token,從而實現(xiàn)業(yè)務鑒權的功能。這種方式通常使用 JWT(JSON Web Token)等工具來實現(xiàn)。在后續(xù)的講解中,我們將詳細介紹這些概念和技術細節(jié)。

手機號碼快捷登錄

獲取手機號碼的前提:

  • 非個人小程序
  • 認證的小程序
  • 非海外的企業(yè)認證

下面是大概業(yè)務流程圖:

獲取對應code

<template>
  <button
    class="login-btn"
    open-type="getPhoneNumber"
    @getphonenumber="getPhoneNumber"
  >
    手機號碼登錄
  </button>
</template>
<script>
export default {
  setup() {
    // 目前該接口針對非個人開發(fā)者,且完成了認證的小程序開放(不包含海外主體)
    const getPhoneNumber = (e) => {
      const { code, errMsg } = e.detail;
      if (errMsg === 'getPhoneNumber:ok') {
        const { data } = await loginByPhone({
          code,
        });
      } else {
        uni.showToast({
          title: errMsg,
        });
      }
    };
    return {
      getPhoneNumber,
    };
  },
};
</script>

后端處理邏輯

// 基于手機號登錄
router.post('/loginByPhone', async function (req, res) {
  try {
    // 1. 獲取 code 和 loginCode
    const { code } = req.body;
    // 2. 獲取接口調(diào)用憑據(jù),理論上這里需要緩存 access_token,避免頻繁調(diào)用接口
    const { access_token } = await request.get('/cgi-bin/token', {
      grant_type: 'client_credential',
      appid,
      secret,
    });
    // 3. 獲取手機號
    const { phone_info } = await request.post(
      `/wxa/business/getuserphonenumber?access_token=${access_token}`,
      {
        code,
      }
    );
    // 4. 查找用戶是否已經(jīng)注冊
    // 4.1 根據(jù) phone 查找用戶
    const { purePhoneNumber } = phone_info;
    models.user
      .findOne({
        where: {
          purePhoneNumber,
        },
      })
      .then((user) => {
        if (user) {
          // 4.2 如果用戶已經(jīng)注冊,返回用戶信息
          res.json(
            new Result({
              data: user,
              msg: '登錄成功',
            })
          );
        } else {
          // 4.3 如果用戶沒有注冊,創(chuàng)建用戶并返回用戶信息
          const username = randomUserName();
          models.user
            .create({
              nickname: username,
              avatar: '/uploads/default-avatar.png',
              phone: phone_info.purePhoneNumber,
            })
            .then((user) => {
              res.json(
                new Result({
                  data: user,
                  msg: '登錄成功',
                })
              );
            });
        }
      });
  } catch (error) {
    res.json(
      new Result({
        code: 'BIZ_ERROR',
        msg: error.errmsg || error.message,
      })
    );
  }
});

上面代碼,實現(xiàn)獲取手機號碼并使用手機號碼作為唯一標識,進行用戶創(chuàng)建和查找的操作。

從登錄的角度來看,使用手機號碼作為唯一標識符是沒有問題的。然而,如果用戶嘗試使用非手機號碼(例如 OpenID)進行登錄,并在數(shù)據(jù)庫中找不到匹配的記錄時,系統(tǒng)會創(chuàng)建一個新的賬號。這可能導致同一個用戶在系統(tǒng)中存在多個賬號的情況。

為了優(yōu)化這種情況,可以考慮以下幾種方法:

  • 當用戶使用 openid 登錄后,檢測未綁定手機號碼時,進行號碼綁定
  • 當用戶使用手機號碼登錄時,提前調(diào)用 wx.login 獲取對應 code,換取 openid 把他與手機號碼進行關聯(lián)

現(xiàn)在基于上面的代碼,采用第二種方案,只需要微調(diào)下代碼就能解決這個問題。

  • 登錄時把 wx.login 獲取 code 傳遞給后端
<template>
  <button
    class="login-btn"
    open-type="getPhoneNumber"
    @getphonenumber="getPhoneNumber"
  >
    手機號碼登錄
  </button>
</template>
<script>
export default {
  setup() {
    // 目前該接口針對非個人開發(fā)者,且完成了認證的小程序開放(不包含海外主體)
    const getPhoneNumber = (e) => {
      const { code, errMsg } = e.detail;
      if (errMsg === 'getPhoneNumber:ok') {
        uni.login({
          success: async (res) => {
            if (res.errMsg === 'login:ok') {
              const { data } = await loginByPhone({
                code,
                loginCode: res.code,
              });
              userStore.setUserInfo(data);
              uni.navigateBack();
            }
          },
          fail(e) {
            uni.showToast({
              title: e.message,
            });
          },
        });
      } else {
        uni.showToast({
          title: errMsg,
        });
      }
    };
    return {
      getPhoneNumber,
    };
  },
};
</script>

服務端基于 loginCode 換取 openid

// 基于手機號登錄
router.post('/loginByPhone', async function (req, res) {
  try {
    // 1. 獲取 code 和 loginCode
    const { code, loginCode } = req.body;
    // 2. 獲取接口調(diào)用憑據(jù),理論上這里需要緩存 access_token,避免頻繁調(diào)用接口
    const { access_token } = await request.get('/cgi-bin/token', {
      grant_type: 'client_credential',
      appid,
      secret,
    });
    // 3. 獲取 openid
    const { openid } = await request.get('/sns/jscode2session', {
      appid,
      secret,
      js_code: loginCode,
      grant_type,
    });
    // 4. 獲取手機號
    const { phone_info } = await request.post(
      `/wxa/business/getuserphonenumber?access_token=${access_token}`,
      {
        code,
        openid,
      }
    );
    // 5. 查找用戶是否已經(jīng)注冊
    // 5.1 根據(jù) openid 查找用戶
    models.user
      .findOne({
        where: {
          openid,
        },
      })
      .then((user) => {
        if (user) {
          // 5.2 如果用戶已經(jīng)注冊,返回用戶信息
          res.json(
            new Result({
              data: user,
              msg: '登錄成功',
            })
          );
        } else {
          // 5.3 如果用戶沒有注冊,創(chuàng)建用戶并返回用戶信息
          const username = randomUserName();
          models.user
            .create({
              nickname: username,
              openid,
              avatar: '/uploads/default-avatar.png',
              phone: phone_info.purePhoneNumber,
            })
            .then((user) => {
              res.json(
                new Result({
                  data: user,
                  msg: '登錄成功',
                })
              );
            });
        }
      });
  } catch (error) {
    res.json(
      new Result({
        code: 'BIZ_ERROR',
        msg: error.errmsg || error.message,
      })
    );
  }
});

這種方案被視為最佳的解決方案,能夠有效解決多賬號和綁定手機號碼等問題。 實際上,采用哪種方式取決于具體的業(yè)務場景,因為在某些情況下,用戶可能會擔心手機號碼泄露而不愿采用這種方式。

注意

  • 獲取手機號碼是需要收費,每次調(diào)用需要 0.03 元。
  • wx.logingetPhoneNumber 中獲取的 code 不是同一個

總結

  • 基于 openid 或 手機號碼快捷登錄
  • 獲取手機號碼前置條件
  • 如何解決多賬號的問題
  • 講解前端、后端、微信登錄過程中完整交互流程,方便更好去理解小程序登錄

以上就是微信小程序常見的兩種登錄方式詳解的詳細內(nèi)容,更多關于小程序登錄方式的資料請關注腳本之家其它相關文章!

相關文章

  • uniapp微信小程序授權登錄并獲取手機號的方法

    uniapp微信小程序授權登錄并獲取手機號的方法

    這篇文章主要給大家介紹了關于uniapp微信小程序授權登錄并獲取手機號的相關資料,我們在uniapp開發(fā)微信小程序的過程中,經(jīng)常需要在微信端登錄,需要的朋友可以參考下
    2023-06-06
  • 詳解微信小程序文件下載--視頻和圖片

    詳解微信小程序文件下載--視頻和圖片

    這篇文章主要介紹了微信小程序文件下載視頻和圖片,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • JavaScript 高效運行代碼分析

    JavaScript 高效運行代碼分析

    傳統(tǒng)上,網(wǎng)頁中不會有大量的腳本,至少腳本很少會影響網(wǎng)頁的性能。
    2010-03-03
  • javascript實現(xiàn)列表滾動的方法

    javascript實現(xiàn)列表滾動的方法

    這篇文章主要介紹了javascript實現(xiàn)列表滾動的方法,較為詳細的分析了javascript實現(xiàn)列表滾動的頁面布局及javascript滾動效果的實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • 常用JS代碼實例小結

    常用JS代碼實例小結

    跟網(wǎng)上的一些常用的不太一樣,個人都有個人常用的代碼,大家看到好東西,不一定什么都會,起碼要知道有這么個東西。方便以后用也方便找。
    2009-04-04
  • js replace() 文本替換你所不知的

    js replace() 文本替換你所不知的

    今天看了一個函數(shù),功能是把形如word-word的字符串轉化為wordWord
    2010-03-03
  • Ant Design Pro 下實現(xiàn)文件下載的實現(xiàn)代碼

    Ant Design Pro 下實現(xiàn)文件下載的實現(xiàn)代碼

    這篇文章主要介紹了Ant Design Pro 下實現(xiàn)文件下載的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-12-12
  • js截取小數(shù)點后幾位的寫法

    js截取小數(shù)點后幾位的寫法

    截取小數(shù)點后幾位的方法有很多,下面為大家介紹下使用js是如何實現(xiàn)的
    2013-11-11
  • GoJs中導出圖片或者SVG實現(xiàn)示例詳解

    GoJs中導出圖片或者SVG實現(xiàn)示例詳解

    這篇文章主要為大家介紹了GoJs中導出圖片或者SVG實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • 定時器(setTimeout/setInterval)調(diào)用帶參函數(shù)失效解決方法

    定時器(setTimeout/setInterval)調(diào)用帶參函數(shù)失效解決方法

    setInterval()方法可按照指定的周期(以毫秒計)來調(diào)用函數(shù)或計算表達式,setTimeout()方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計算表達式,詳細使用方法可以參考下本文
    2013-03-03

最新評論