1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        小程序用戶(hù)登錄架構(gòu)設(shè)計(jì)

        共 13280字,需瀏覽 27分鐘

         ·

        2021-05-30 12:55

        點(diǎn)擊下方“全棧前端精選”關(guān)注公眾號(hào)

        回復(fù)“1”加入前端群

        1. 背景

        上一篇文章《小程序靜默登錄方案設(shè)計(jì)》提到過(guò),小程序可以通過(guò)微信官方提供的登錄能力方便地獲取微信提供的用戶(hù)身份標(biāo)識(shí),快速建立小程序內(nèi)的用戶(hù)體系。

        即「靜默登錄」,通過(guò)調(diào)用 wx.login 獲取到 code ,將其發(fā)送到開(kāi)發(fā)者后端,開(kāi)發(fā)者后端通過(guò)接口去微信后端換取到 openid 和 sessionKey(現(xiàn)在會(huì)將 unionid 也一并返回)后,然后把自定義登錄態(tài) 3rd_session(本業(yè)務(wù)命名為auth-token) 返回給前端,就已經(jīng)完成登錄行為了。

        理論上,開(kāi)發(fā)者后端可以通過(guò) openid識(shí)別用戶(hù),也能通過(guò)unionid關(guān)聯(lián)同主體的多個(gè)小程序、公眾號(hào)、app,實(shí)現(xiàn)數(shù)據(jù)互通,從而為每一個(gè)用戶(hù)創(chuàng)建獨(dú)一無(wú)二的uid(本業(yè)務(wù)自定義的用戶(hù) id),在「微信生態(tài)」中建立成熟用戶(hù)體系。

        然而,對(duì)于復(fù)雜的電商跨端應(yīng)用,比如pc、h5小程序,不同渠道注冊(cè)的uid是不同的,用戶(hù)登錄后難以對(duì)各個(gè)渠道的交易、促銷(xiāo)、收藏等數(shù)據(jù)進(jìn)行整合。因此,要實(shí)現(xiàn)跨端的用戶(hù)體系數(shù)據(jù)互通,就需要提供一個(gè)唯一的用戶(hù)標(biāo)識(shí)——手機(jī)號(hào)。這便是本文重點(diǎn)講述的「用戶(hù)登錄」,即「游客態(tài)」轉(zhuǎn)變成「會(huì)員態(tài)」的過(guò)程。

        2. 「用戶(hù)登錄」流程

        上一篇文章《小程序靜默登錄方案設(shè)計(jì)》中提過(guò),當(dāng)新用戶(hù)第一次進(jìn)入小程序時(shí),便會(huì)觸發(fā)「靜默登錄」,這個(gè)過(guò)程對(duì)用戶(hù)是無(wú)感知的。但此時(shí)開(kāi)發(fā)者服務(wù)端已經(jīng)為該用戶(hù)定義了uid,并下發(fā)auth-token給小程序端,對(duì)于一些需要鑒權(quán)的請(qǐng)求,服務(wù)端可以根據(jù)請(qǐng)求攜帶的auth-token精確識(shí)別是哪個(gè)用戶(hù)發(fā)起的行為。

        然而,類(lèi)似加購(gòu)、下單領(lǐng)券等用戶(hù)行為,涉及到跨端數(shù)據(jù)的整合,在執(zhí)行用戶(hù)操作之前,會(huì)判斷用戶(hù)是否登錄,如若用戶(hù)未登錄,則跳轉(zhuǎn)登錄頁(yè)面,整個(gè)流程如下所示:

        登錄流程圖

        比如在「用戶(hù)中心」頁(yè)面點(diǎn)擊「我的訂單」,由于此時(shí)用戶(hù)未登錄,跳轉(zhuǎn)到登錄頁(yè)面,可以選擇以下兩種登錄方式:

        1. 選擇 「微信授權(quán)登錄」,彈出授權(quán)手機(jī)號(hào)信息彈窗,點(diǎn)擊「允許」,此時(shí)用戶(hù)登錄成功。
        2. 選擇 「手機(jī)快捷登錄」,輸入手機(jī)號(hào),使用 「驗(yàn)證碼」 或者 「密碼」 進(jìn)行登錄,登錄成功跳轉(zhuǎn)回到「用戶(hù)中心」頁(yè)面。

        上述步驟已經(jīng)完成了「用戶(hù)登錄」,用戶(hù)可以正常的執(zhí)行加購(gòu)、領(lǐng)券、下單等操作。為了提升用戶(hù)體驗(yàn),需要對(duì) 「會(huì)員信息」 進(jìn)行維護(hù) ,比如昵稱(chēng)、頭像、性別、生日等信息,最簡(jiǎn)單的方法是 獲取「微信授權(quán)用戶(hù)信息」。觸發(fā)時(shí)機(jī)分為以下兩種:

        1. 用戶(hù)第一次選擇 「微信授權(quán)登錄」 成功后跳轉(zhuǎn)授權(quán)用戶(hù)信息頁(yè)面,點(diǎn)擊 「授權(quán)用戶(hù)信息」,彈出授權(quán)用戶(hù)信息彈窗。點(diǎn)擊「允許」,跳轉(zhuǎn)回「用戶(hù)中心」頁(yè)面。
        2. 在「用戶(hù)中心」頁(yè)面點(diǎn)擊頭像昵稱(chēng)區(qū)域,彈出授權(quán)用戶(hù)信息彈窗,點(diǎn)擊「允許」,更新「會(huì)員信息」并跳轉(zhuǎn)用戶(hù)信息編輯頁(yè)面。

        3. 「用戶(hù)登錄」方案設(shè)計(jì)

        3.1 架構(gòu)

        用戶(hù)登錄架構(gòu)

        「用戶(hù)登錄」方案架構(gòu)如上圖所示,將所有登錄相關(guān)功能抽象到 「service 層」(本項(xiàng)目將其命名為session),供 「業(yè)務(wù)層」 調(diào)用。該 「service 層」 主要分為以下兩個(gè)模塊:

        3.1.1 libs - 提供登錄相關(guān)的類(lèi)方法供「業(yè)務(wù)層」調(diào)用

        1. 封裝session類(lèi),提供類(lèi)方法供「業(yè)務(wù)層」調(diào)用。主要有以下幾種方法:
        方法名 功能 使用場(chǎng)景
        silentLogin 發(fā)起靜默登錄 -
        login 登錄,silentLogin方法的一層封裝 用于小程序啟動(dòng)時(shí)發(fā)起靜默登錄
        refreshLogin 刷新登錄態(tài),silentLogin方法的一層封裝 用于登錄態(tài)過(guò)期時(shí)發(fā)起靜默登錄
        ensureSessionKey 驗(yàn)證sessionKey是否過(guò)期,過(guò)期則刷新登錄態(tài) 綁定微信授權(quán)手機(jī)號(hào)時(shí)驗(yàn)證是否過(guò)期,過(guò)期則得重新彈窗授權(quán)
        bindPhone 綁定微信授權(quán)手機(jī)號(hào) 微信授權(quán)手機(jī)號(hào)彈窗點(diǎn)擊「允許」觸發(fā)
        updateUser 綁定微信授權(quán)用戶(hù)信息 微信授權(quán)用戶(hù)信息點(diǎn)擊「允許」觸發(fā)
        getCurrentAuthStep 獲取當(dāng)前用戶(hù)登錄所屬階段 詳見(jiàn)下文
        mustAuth 各種觸發(fā)場(chǎng)景攔截判斷是否需要登錄 詳見(jiàn)下文

        當(dāng)然,session類(lèi)中還封裝了一些方法用于與storage交互,比如獲取storage中的auth-token用于各種鑒權(quán)請(qǐng)求攜帶等等。session類(lèi)也提供的一些拓展方法,比如注銷(xiāo)賬號(hào)、解綁手機(jī)號(hào)等等用于后續(xù)需求迭代。

        1. 裝飾器:

          • must-authmustAuth類(lèi)方法的裝飾器,便于業(yè)務(wù)層各種場(chǎng)景觸發(fā)登錄。
          • fuse-line熔斷機(jī)制,如果短時(shí)間內(nèi)多次調(diào)用,則停止響應(yīng)一段時(shí)間,類(lèi)似于 TCP 慢啟動(dòng)。用于解決refreshLogin、login等方法的并發(fā)處理問(wèn)題。
          • single-queue單隊(duì)列模式,同一時(shí)間,只允許一個(gè)正在過(guò)程中的網(wǎng)絡(luò)請(qǐng)求。請(qǐng)求被鎖定之后,同樣的請(qǐng)求都會(huì)被推入隊(duì)列,等待進(jìn)行中的請(qǐng)求返回后,消費(fèi)同一個(gè)結(jié)果。用于解決refreshLoginlogin等方法的并發(fā)處理問(wèn)題。

        3.1.2 ui - 提供通用組件供業(yè)務(wù)層調(diào)用

        1. 基礎(chǔ)組件user-containerphone-container分別是獲取「微信授權(quán)用戶(hù)信息」和獲取「微信授權(quán)手機(jī)號(hào)」的純 UI 單元組件,給通用組件使用。
        2. behavior 類(lèi):拿到授權(quán)數(shù)據(jù)后需要發(fā)送給服務(wù)端進(jìn)行存儲(chǔ),也需要執(zhí)行一些跳轉(zhuǎn)邏輯判斷,這些都抽象成行為類(lèi)封裝在auth-flow中,供通用組件使用。
        3. 通用組件:共用一個(gè)行為類(lèi),區(qū)別在于auth-flow-container用于頁(yè)面,auth-flow-popup用于彈窗。如下所示,小程序只有微信授權(quán)功能,則可以通過(guò)彈窗完成授權(quán)。如小程序同時(shí)提供手機(jī)號(hào)驗(yàn)證碼和密碼登錄等功能,則需跳轉(zhuǎn)特定登錄頁(yè)面。
        登錄流程-彈窗

        3.2 libs

        3.2.1 用戶(hù)身份定義

        用戶(hù)登錄階段

        綜上所示,用戶(hù)登錄的階段可以分為以下三步:

        // 用戶(hù)登錄的階段
        export enum AuthStepType {
          // 階段一:游客態(tài):靜默登錄成功,未綁定手機(jī)號(hào),無(wú)用戶(hù)信息
          ONE = 1,
          // 階段二:會(huì)員態(tài):用戶(hù)登錄成功,已綁定手機(jī)號(hào),無(wú)用戶(hù)信息
          TWO = 2,
          // 階段三:會(huì)員信息態(tài):用戶(hù)登錄成功,已綁定手機(jī)號(hào),有用戶(hù)信息
          THREE = 3,
        }

        那么如何判斷用戶(hù)此時(shí)處于哪個(gè)步驟,基于「靜默登錄」的啟發(fā),原本「靜默登錄」成功開(kāi)發(fā)者后端會(huì)將自定義登錄態(tài) auth-token返回給前端,此處請(qǐng)求可以攜帶返回「用戶(hù)信息」,同auth-token一起命名為session存儲(chǔ)在本地storage當(dāng)「用戶(hù)登錄」或者「更新用戶(hù)信息」時(shí),會(huì)同步更新storagekeysession的數(shù)據(jù),從而通過(guò)這些用戶(hù)數(shù)據(jù)判斷當(dāng)前用戶(hù)處于哪一個(gè)登錄階段。

        以下表格列出了session存儲(chǔ)的部分重要的屬性以及在三個(gè)階段屬性對(duì)應(yīng)的值。

        屬性 定義 游客態(tài) 會(huì)員態(tài) 會(huì)員信息態(tài)
        authToken 自定義登錄態(tài) '0d5bad172...' '0d5bad172...' '0d5bad172...'
        uid 用戶(hù) id '001' '001' '001'
        busiIdentity 用戶(hù)身份定義 'VISIT' 'MEMBER' 'MEMBER'
        nickName 用戶(hù)昵稱(chēng) '' 'u_a1bk45' 'rileycai'
        headUrl 頭像鏈接 '' '' 'www.xx.com/image/...'
        phone 手機(jī)號(hào)碼 '' '17600888888' '17600888888'
        ... 其它用戶(hù)信息 ... ... ...

        注意: 會(huì)員態(tài)和會(huì)員信息態(tài)的busiIdentity值均為MEMBER,區(qū)分會(huì)員態(tài)和會(huì)員信息態(tài)可以通過(guò)用戶(hù)昵稱(chēng)和頭像等字段,比如用戶(hù)登錄成功會(huì)為用戶(hù)生成以'u_'開(kāi)頭的默認(rèn)昵稱(chēng)和默認(rèn)為空的用戶(hù)頭像鏈接。

        判斷用戶(hù)此時(shí)處于哪個(gè)步驟的代碼如下:

          // 獲取當(dāng)前授權(quán)階段
          public getCurrentAuthStep(): AuthStepType {
            // 切換賬號(hào)登錄的時(shí)候,始終返回AuthStepType.ONE
            const loginMode = this.getLoginMode();
            if (loginMode === LoginMode.SWITCH_ACCOUNT) return AuthStepType.ONE;

            // 用戶(hù)身份定義非會(huì)員返回AuthStepType.ONE
            const userInfo = this.getUser();
            if (userInfo?.busiIdentity !== 'MEMBER'return AuthStepType.ONE;

            // 初次登錄,未授權(quán)用戶(hù)信息,返回AuthStepType.TWO
            if (userInfo.nickName.substring(02) === 'u_' && !userInfo.headUrl)
              return AuthStepType.TWO;

            // 都有,返回AuthStepType.THREE
            return AuthStepType.THREE;
          }

        3.2.2 用戶(hù)登錄觸發(fā)場(chǎng)景

        前面提到過(guò),「用戶(hù)登錄」的 目的是為了整合各個(gè)渠道的交易、促銷(xiāo)、收藏等數(shù)據(jù),針對(duì)電商小程序,目前總結(jié)的需要用戶(hù)登錄的場(chǎng)景如下所示:

        用戶(hù)登錄場(chǎng)景

        即當(dāng)用戶(hù)登錄小程序時(shí),可以正常瀏覽瀏覽商品,只有觸發(fā)某些特定行為,比如領(lǐng)券、加購(gòu)、收藏、下單等,才會(huì)判斷用戶(hù)是否處于登錄狀態(tài),如未登錄,跳轉(zhuǎn)登錄頁(yè)面。

        如下所示,封裝mustAuth方法進(jìn)行攔截,未登錄則跳轉(zhuǎn)登錄頁(yè)面:

        export default class Session {
          ...
          public mustAuth({
            mustAuthStep = AuthStepType.TWO, // 傳人參數(shù),需要授權(quán)的LEVEL
          } = {}): Promise<void> {
            // 當(dāng)前階段處于會(huì)員態(tài)(2)或者會(huì)員信息態(tài)(3),執(zhí)行resolve操作
            if (this.getCurrentAuthStep() >= mustAuthStep) return Promise.resolve();
            // 當(dāng)前階段處于游客態(tài)(1),跳轉(zhuǎn)登錄頁(yè)
            Navigator.gotoPage('/login/home');
            // 執(zhí)行reject操作
            return Promise.reject();
          }
        }

        上述代碼是跳轉(zhuǎn)頁(yè)面攔截,對(duì)于彈窗而言,需要把彈窗注入base-page(每個(gè)頁(yè)面都需要引入的通用組件,封裝每個(gè)頁(yè)面都需要使用的通用方法,比如錯(cuò)誤處理等)中,通過(guò) id 查找到彈窗組件,并進(jìn)行調(diào)用。

        export default class Session {
          ...
           public mustAuth({
            mustAuthStep = AuthStepType.TWO, // 需要授權(quán)的LEVEL
            popupCompName = 'auth-flow-popup',
          } = {}): Promise<void> {
            // 當(dāng)前階段處于會(huì)員態(tài)(2)或者會(huì)員信息態(tài)(3),執(zhí)行resolve操作
            if (this.getCurrentAuthStep() >= mustAuthStep) return Promise.resolve();
            // 獲取彈窗組件
            const pages = getCurrentPages();
            const curPage = pages[pages.length - 1];
            const context = curPage.$$basePage || curPage;
            const popupComp = context.selectComponent(`#${popupCompName}`);
            // 容錯(cuò)處理
            if (!popupComp) {
              return Promise.reject(
                new Error(
                  "當(dāng)前頁(yè)面未找到 #auth-popup 組件,請(qǐng)參考 'doc/登錄組件的使用方式.md'",
                ),
              );
            }
            // 調(diào)用彈窗組件方法
            popupComp.setMustAuthStep(mustAuthStep);
            popupComp.nextStep();
            // 等待授權(quán)成功回調(diào)
            return this.waitAuth();
          }
        }

        各個(gè)業(yè)務(wù)使用時(shí)可以通過(guò)session.mustAuth().then(() => {...});進(jìn)行調(diào)用,為了提高使用體驗(yàn),也可以使用裝飾器@mustAuth()來(lái)修飾各個(gè)業(yè)務(wù)需求 類(lèi)的方法,裝飾器源碼如下:

        /**
         * 登錄檢查裝飾器,使用該裝飾器的方法,會(huì)先執(zhí)行授權(quán)檢查,如果未授權(quán),將跳轉(zhuǎn)登錄頁(yè)面
         */

        export default function mustAuth(option = {}{
          return function(
            _target: Record<string, any>,
            _propertyName: string,
            descriptor: TypedPropertyDescriptor<(...args: any[]
        ) => any>,
          ) 
        {
            const method = descriptor.value;
            descriptor.value = function(...args: any[]{
              if (!session) return;
              // 登錄攔截
              return session.mustAuth(option).then(() => {
                if (method) return method.apply(this, args);
              });
            };
          };
        }

        3.3 UI

        3.3.1 基礎(chǔ)組件

        1. phone-container 組件

        因?yàn)樾枰脩?hù)主動(dòng)觸發(fā)才能發(fā)起獲取微信授權(quán)手機(jī)號(hào)接口,需用 button 組件的點(diǎn)擊來(lái)觸發(fā)。組件代碼如下所示:

        // index.wxml
         <button class="reset-button" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber" hover-class="none" disabled="{{disabled}}"><slot></slot></button>

        /
        / index.ts
        export default class PhoneContainer extends BaseComponent {
          getPhoneNumber(
            e: WechatMiniprogram.Event<WechatMiniprogram.GetPhoneNumberCallbackResult>,
          ) {
            this.triggerEvent('getphonenumber', { ...e.detail,  authType: AuthType.PHONE,});
          }
        }

        phone-container是一個(gè)純 UI 組件,通過(guò)triggerEvent事件將獲取手機(jī)號(hào)數(shù)據(jù)傳遞給父組件,

        2. user-container 組件

        user-container組件是獲取微信授權(quán)用戶(hù)信息的純 UI 組件,之前通過(guò)<button open-type="getUserInfo" bindgetUserInfo="getUserInfo"/>的方式進(jìn)行獲取。2021 年 2 月 23 日,微信團(tuán)隊(duì)發(fā)布了《小程序登錄、用戶(hù)信息相關(guān)接口調(diào)整說(shuō)明》,新增getUserProfile接口替代原來(lái)的wx.getUserInfo,來(lái)獲取用戶(hù)頭像、昵稱(chēng)、性別及地區(qū)信息,也是通過(guò)button 組件的點(diǎn)擊來(lái)觸發(fā)。兩者的區(qū)別如下圖所示:

        獲取用戶(hù)信息接口區(qū)別

        2012 年 4 月 13 日之前,使用wx.getUserInfo彈出授權(quán)彈窗時(shí),如果用戶(hù)點(diǎn)擊允許授權(quán),那么會(huì)記錄用戶(hù)的行為,下次再點(diǎn)擊時(shí),不會(huì)彈窗而是直接將授權(quán)結(jié)果返回。4 月 13 日之后后,使用wx.getUserProfile,開(kāi)發(fā)者每次通過(guò)該接口獲取用戶(hù)個(gè)人信息均需用戶(hù)確認(rèn),因此需要妥善保管用戶(hù)授權(quán)的頭像昵稱(chēng),避免重復(fù)彈窗。

        3.3.2 行為類(lèi)

        如下圖所示,auth-flow行為類(lèi)主要封裝用戶(hù)、小程序、服務(wù)端三者之間的交互邏輯。

        用戶(hù)行為

        在「微信授權(quán)登錄」過(guò)程中,小程序拿到加密的encryptedDataiv數(shù)據(jù),將其和攜帶的auth-token一起發(fā)送給開(kāi)發(fā)者服務(wù)器,服務(wù)端通過(guò)auth-token鑒權(quán)識(shí)別這個(gè)用戶(hù),并使用靜默登錄成功獲取的session_key(對(duì)稱(chēng)解密密鑰)對(duì)encryptedDataiv數(shù)據(jù)進(jìn)行對(duì)稱(chēng)解密,獲取該用戶(hù)的手機(jī)號(hào),將手機(jī)號(hào)與uid綁定,此時(shí)該用戶(hù)成功注冊(cè)會(huì)員,并將會(huì)員信息返回給小程序端。

        小程序端更新本地storage存儲(chǔ)的session數(shù)據(jù),此時(shí)busiIdentity的值已經(jīng)從VISIT更新為MEMBER,用戶(hù)身份轉(zhuǎn)變?yōu)?strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">會(huì)員態(tài),登錄成功。

        在「授權(quán)用戶(hù)信息」的過(guò)程中,小程序調(diào)用wx.getUserProfile方法拿到用戶(hù)數(shù)據(jù),并將這些數(shù)據(jù)與攜帶的auth-token一起發(fā)送給開(kāi)發(fā)者服務(wù)器,服務(wù)端通過(guò)auth-token鑒權(quán)識(shí)別這個(gè)用戶(hù),更新該用戶(hù)的信息并將新的會(huì)員數(shù)據(jù)返回給小程序端。

        小程序端更新本地storage存儲(chǔ)的session數(shù)據(jù),此時(shí)用戶(hù)昵稱(chēng)和頭像均已更新,用戶(hù)身份轉(zhuǎn)變?yōu)?strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">會(huì)員信息態(tài),授權(quán)成功。

        眼尖的讀者一定觀察到了,時(shí)序圖中還對(duì)微信頭像做了轉(zhuǎn)存。這是因?yàn)?strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">用戶(hù)在微信端修改微信頭像后,之前「授權(quán)用戶(hù)信息」獲取的微信頭像鏈接就會(huì)失效,因此開(kāi)發(fā)者應(yīng)該在自己獲取用戶(hù)信息后,將頭像保存下來(lái),避免微信頭像 URL 失效后的異常情況。

        3.3.3 通用組件

        通用組件是對(duì)基礎(chǔ)組件和行為類(lèi)的二次封裝,主要是為業(yè)務(wù)層提供彈窗登錄和頁(yè)面登錄兩種能力。

        4. 總結(jié)

        我們將用戶(hù)登錄能力從業(yè)務(wù)層中抽象出來(lái),統(tǒng)一封裝在service層,便于復(fù)用。本文主要講述的是service層的架構(gòu),對(duì)于業(yè)務(wù)層的邏輯實(shí)現(xiàn)并沒(méi)有多加累贅。下列表格以小程序端為例,簡(jiǎn)述了「靜默登錄」和「用戶(hù)登錄」整套方案的前后端邏輯實(shí)現(xiàn)。

        業(yè)務(wù)場(chǎng)景 用戶(hù)感知 前端處理邏輯 后端處理邏輯 補(bǔ)充說(shuō)明
        掃碼搜索等各種方式進(jìn)入小程序 無(wú) 1、判斷:當(dāng)前小程序是否緩存了登錄態(tài)auth-token 且使用wx.checkSeesion檢查當(dāng)前用戶(hù)在小程序中登錄態(tài)是否過(guò)期,過(guò)期執(zhí)行步驟 2;

        2、使用wx.login獲取認(rèn)證信息,請(qǐng)求后端wxLogin接口獲取微信小程序認(rèn)證默認(rèn)綁定的用戶(hù)身份以及登錄態(tài)auth-token。 1、解析微信加密信息獲取認(rèn)證身份openidunionId;


        2、查找openid是否已經(jīng)綁定了對(duì)應(yīng)的用戶(hù),若綁定直接返回并為其生成對(duì)應(yīng)的登錄態(tài)auth-token;
        3、新用戶(hù)會(huì)根據(jù)openid為其自動(dòng)生成一個(gè)用戶(hù)身份uid(見(jiàn)右補(bǔ)充說(shuō)明)。| a、存在聚合根標(biāo)識(shí)unionId && 有用戶(hù)信息:將已有聚合根用戶(hù)對(duì)應(yīng)的exUid直接映射到當(dāng)前uid下;
        b、存在聚合根標(biāo)識(shí)unionId && 無(wú)用戶(hù)信息:根據(jù)unionId生成對(duì)應(yīng)的賬號(hào),但和opneid對(duì)應(yīng)的uid一致;
        c、不存在聚合根標(biāo)識(shí):直接為對(duì)應(yīng)openid初始化一個(gè)uid。| | 收藏、加購(gòu)下單、領(lǐng)券等操作 | 攔截跳轉(zhuǎn) | 1、判斷:當(dāng)前用戶(hù)身份處于游客態(tài),跳轉(zhuǎn)登錄頁(yè)面。| 對(duì)應(yīng)域服務(wù)后端接口可以根據(jù)請(qǐng)求攜帶的auth-token進(jìn)行鑒權(quán),判斷用戶(hù)是否有操作權(quán)限 | - | | 用戶(hù)登錄 或者 切換賬號(hào) | 選擇:
        1、授權(quán)微信手機(jī)號(hào)登錄;
        2、輸入手機(jī)號(hào)并使用驗(yàn)證碼/密碼登錄 | 1、用戶(hù)選擇授權(quán)手機(jī)號(hào)登錄,后端會(huì)根據(jù)上一次靜默登錄的sesssionKey解密,如果解密失敗需要重新走一遍靜默登錄后再讓客戶(hù)重試。
        2、用戶(hù)選擇通過(guò)驗(yàn)證碼登錄時(shí),需關(guān)注驗(yàn)證碼時(shí)效和重試機(jī)制,并有錯(cuò)誤處理邏輯;
        3、用戶(hù)選擇密碼登錄時(shí),后臺(tái)會(huì)返回賬戶(hù)未注冊(cè)或賬號(hào)密碼不對(duì)等錯(cuò)誤,需要有獨(dú)立邏輯跳轉(zhuǎn)驗(yàn)證碼注冊(cè)或找回密碼
        4、以上三種方式都需要攜帶auth-token進(jìn)行鑒權(quán) | 1、根據(jù)auth-token獲取當(dāng)前的渠道基本認(rèn)證賬戶(hù)openid-unionId-uid;
        2、授權(quán)手機(jī)號(hào)登錄時(shí)需要先解密出手機(jī)號(hào),此時(shí)不需要校驗(yàn),輸入手機(jī)號(hào)登錄時(shí)需要會(huì)走「密碼」或「驗(yàn)證碼」校驗(yàn),密碼校驗(yàn)會(huì)攔截賬號(hào)不存在或密碼錯(cuò)誤的場(chǎng)景;
        3、根據(jù)手機(jī)號(hào)判斷當(dāng)前聚合根下是否存在對(duì)應(yīng)的手機(jī)號(hào)渠道賬號(hào)(綁定流程見(jiàn)右補(bǔ)充說(shuō)明)。
        4、返回登錄結(jié)果。| a、手機(jī)號(hào)已存在:將已存在的用戶(hù)exUid綁定至當(dāng)前登錄態(tài)賬號(hào);
        b、手機(jī)號(hào)不存在 && 用戶(hù)身份是游客:將手機(jī)號(hào)和游客對(duì)應(yīng)的uid進(jìn)行綁定
        c、手機(jī)號(hào)不存在 && 用戶(hù)身份是會(huì)員:為手機(jī)號(hào)生成一個(gè)新的newUid,并將當(dāng)前登錄的 openid 渠道賬戶(hù)綁定至該newUid。

        作者: 蔡小真

        https://juejin.cn/post/6945264484491460638


        推薦閱讀

        小程序如何生成海報(bào)分享朋友圈

        瀏覽 33
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            www逼逼 | 被强迫各种姿势侵犯np | 曰夲卖婬片免费看9.1 | 动漫黄| 99久久婷婷国产综合精品电影 | 国产一区二区电影 | 日熟妇| 十八禁网站免费看 | 豆花视频在线入口www | 操的好爽视频 |