Мини-программа Логин пользователя Архитектура Дизайн

Апплет WeChat
Мини-программа Логин пользователя Архитектура Дизайн

1. Предпосылки

предыдущий пост«Дизайн схемы тихого входа в небольшую программу»Как уже упоминалось, мини-программа может легко получить идентификатор пользователя, предоставленный WeChat, с помощью возможности входа в систему, предоставляемой официальным WeChat, и быстро установить пользовательскую систему в мини-программе.

То есть «тихий вход», позвонивwx.loginполучитьcode, отправить его на серверную часть разработчика, и серверная часть разработчика переходит на серверную часть WeChat через интерфейс в обмен наopenidиsessionKey(сейчас будетunionidтакже вернуть), а затем поставить пользовательский статус входа3rd_session(Этот бизнес называетсяauth-token) возвращается к внешнему интерфейсу, и поведение при входе завершено.

Теоретически бэкэнд разработчика может пройтиopenidИдентифицировать пользователей, в том числе с помощьюunionidСвяжите несколько небольших программ, официальных учетных записей и приложений с одним и тем же субъектом для реализации обмена данными, тем самым создавая уникальную уникальность для каждого пользователя.uid(идентификатор пользователя, настроенный этим бизнесом), создайте зрелую пользовательскую систему в «Экологии WeChat».

Однако для сложных кросс-конечных приложений электронной коммерции, таких какpc,h5,小程序, зарегистрированные по разным каналамuidотличается, после входа пользователяСложно интегрировать данные о транзакциях, акциях, сборах и т.д. различных каналов. Следовательно, для обеспечения обмена данными между системами конечных пользователей необходимо предоставить уникальный идентификатор пользователя——Телефонный номер. Это «логин пользователя», которому посвящена эта статья, то есть процесс преобразования «статуса туриста» в «статус члена».

2. Процесс «Вход пользователя»

предыдущий пост«Дизайн схемы тихого входа в небольшую программу»Как упоминалось выше, когда новый пользователь входит в апплет в первый раз, будет запущен «тихий вход».не знает о пользователе. Но в это время сервер разработчика определил пользователяuid, и отправитьauth-tokenДля апплета для некоторых запросов, требующих аутентификации, сервер может нестиauth-tokenОпределите, какой именно пользователь инициировал действие.

Однако подобно加购,下单,领券Дождитесь поведения пользователя, которое включает в себя интеграцию перекрестных данных. Перед выполнением пользовательских операций он будет определять, вошел ли пользователь в систему. Если пользователь не вошел в систему, страница входа будет перескок. Весь процесс как следует:

登录流程图

Например, нажмите «Мой заказ» на странице «Центр пользователя». Поскольку пользователь в данный момент не вошел в систему, он перейдет на страницу входа. Вы можете выбрать следующие два метода входа:

  1. выберите«Авторизованный вход в WeChat», появится всплывающее окно с информацией об авторизованном номере мобильного телефона, нажмите «Разрешить», и пользователь успешно войдет в систему.
  2. выберите«Мобильный быстрый вход», введите номер телефона, используйте"Код верификации"или"пароль"Войдите в систему, и если вы войдете в систему успешно, вы будете перенаправлены на страницу «Центр пользователей».

шаги выше«Вход пользователя» завершен, и пользователи могут совершать дополнительные покупки, купоны и заказы в обычном режиме.. Для улучшения пользовательского опыта необходимо"информация участника"Для обслуживания, такого как псевдоним, аватар, пол, день рождения и другую информацию, проще всегоПолучите «Информацию авторизованного пользователя WeChat». Синхронизация триггера делится на следующие два типа:

  1. Первый выбор пользователя«Авторизованный вход в WeChat»После успеха перейдите на страницу с информацией об авторизованном пользователе, нажмите«Информация авторизованного пользователя», появится всплывающее окно с информацией об авторизованном пользователе. Нажмите «Разрешить», чтобы вернуться на страницу «Центр пользователей».
  2. На странице «Центр пользователя» щелкните область аватара и псевдонима, и появится всплывающее окно с информацией об авторизованном пользователе.Нажмите «Разрешить», чтобы обновить «Информацию об участнике» и перейти на страницу редактирования информации о пользователе.

3. Дизайн схемы «Вход пользователя»

3.1 Архитектура

用户登录架构

Архитектура схемы «Вход пользователя» показана на рисунке выше, которая абстрагирует все функции, связанные с входом в систему, в"сервисный уровень"(Этот проект называет его какsession),за«Бизнес-уровень»перечислить. Должен"сервисный уровень"В основном делится на следующие два модуля:

3.1.1 libs- Обеспечьте методы класса, связанные с входом в систему, для вызова "бизнес-уровня"

  1. упаковкаsessionКласс, предоставляющий методы класса для вызова «бизнес-уровня». В основном это следующие методы:
имя метода Функции сцены, которые будут использоваться
silentLogin Инициировать автоматический вход -
login Авторизоваться,silentLoginинкапсуляция метода Используется для инициирования автоматического входа в систему при запуске апплета.
refreshLogin обновить состояние входа,silentLoginинкапсуляция метода Используется для инициации автоматического входа в систему по истечении срока действия статуса входа.
ensureSessionKey проверятьsessionKeyНезависимо от того, истек ли срок его действия, обновите статус входа в систему, когда он истечет. При привязке авторизованного номера мобильного телефона WeChat проверьте, не истек ли срок его действия.Если срок его действия истек, необходимо повторно авторизовать всплывающее окно.
bindPhone Привязать авторизованный номер мобильного телефона WeChat Всплывающее окно авторизованного номера мобильного телефона WeChat запускается при нажатии кнопки «Разрешить».
updateUser Привязать информацию авторизованного пользователя WeChat Информация авторизованного пользователя WeChat активируется нажатием «Разрешить».
getCurrentAuthStep Получить текущую фазу входа пользователя Подробнее см. ниже
mustAuth Различные сценарии триггеров перехватываются, чтобы определить, требуется ли логин Увидеть ниже

Конечно,sessionКласс также инкапсулирует некоторые методы для использования сstorageвзаимодействие, например получениеstorageсерединаauth-tokenОн используется для выполнения различных запросов аутентификации и так далее.sessionКласс также предоставляет некоторые методы расширения, такие как отмена учетной записи, отвязка номера мобильного телефона и т. д. для последующих итераций запроса.

  1. Декоратор:

    • must-auth:mustAuthДекоратор метода класса удобен для запуска входа в систему в различных сценариях бизнес-уровня.
    • fuse-line:автоматический выключатель, если вызывать его несколько раз в течение короткого периода времени, он перестанет отвечать на определенный период времени, подобно медленному запуску TCP. для решенияrefreshLogin,loginи другие методы параллельной обработки задач.
    • single-queue:режим одиночной очереди, одновременно допускается только один выполняемый сетевой запрос. После того, как запрос заблокирован, тот же запрос будет помещен в очередь, ожидая возврата текущего запроса, потребляя тот же результат. для решенияrefreshLogin,loginи другие методы параллельной обработки задач.

3.1.2 ui- Обеспечьте общие компоненты для вызова бизнес-уровня

  1. основные компоненты:user-containerиphone-containerЭто чистые компоненты пользовательского интерфейса для получения «информации авторизованного пользователя WeChat» и «авторизованного номера мобильного телефона WeChat», которые используются для общих компонентов.
  2. класс поведения: после получения данных авторизации их необходимо отправить на сервер для хранения, а также выполнить некоторые логические оценки перехода, которые абстрагируются в классы поведения и инкапсулируются вauth-flow, для использования общими компонентами.
  3. Общие компоненты: разделить класс поведения, разницаauth-flow-containerдля страниц,auth-flow-popupИспользуется для всплывающих окон. Как показано ниже, апплет имеет только функцию авторизации WeChat, а авторизацию можно пройти через всплывающее окно. Если апплет предоставляет такие функции, как код подтверждения номера мобильного телефона и вход в систему с паролем одновременно, ему необходимо перейти на определенную страницу входа.
登录流程-弹窗

3.2 libs

3.2.1 Определение идентификатора пользователя

用户登录阶段

Таким образом, этап входа пользователя можно разделить на следующие три шага:

// 用户登录的阶段
export enum AuthStepType {
  // 阶段一:游客态:静默登录成功,未绑定手机号,无用户信息
  ONE = 1,
  // 阶段二:会员态:用户登录成功,已绑定手机号,无用户信息
  TWO = 2,
  // 阶段三:会员信息态:用户登录成功,已绑定手机号,有用户信息
  THREE = 3,
}

Итак, как определить, на каком этапе находится пользователь в данный момент, основываясь на вдохновении «тихого входа в систему», исходный «тихий вход», успешный бэкэнд разработчика, будет настраивать статус входа в систему.auth-tokenВернитесь к внешнему интерфейсу, где запрос может содержать и возвращать «информацию о пользователе», так же, как иauth-tokenназваны вместеsessionхранится локальноstorage.Когда «логин пользователя» или «обновление информации о пользователе», он будет обновляться синхронноstorageсерединаkeyзаsessionданные, чтобы определить, на каком этапе входа в систему находится текущий пользователь с помощью этих пользовательских данных.

В следующей таблице перечисленыsessionНекоторые важные свойства сохраняются и соответствующие значения свойств на трех этапах.

Атрибуты определение туристический статус Членство Информация об участниках
authToken пользовательский логин '0d5bad172...' '0d5bad172...' '0d5bad172...'
uid Идентификатор пользователя '001' '001' '001'
busiIdentity Определение идентификатора пользователя 'VISIT' 'MEMBER' 'MEMBER'
nickName Ник пользователя '' 'u_a1bk45' 'rileycai'
headUrl Ссылка на аватар '' '' 'www.xx.com/image/...'
phone номер мобильного телефона '' '17600888888' '17600888888'
... Другая информация о пользователе ... ... ...

Уведомление:Членство и информация о членствеbusiIdentityзначениеMEMBER, состояние участника и состояние информации о члене можно отличить по таким полям, как псевдоним пользователя и аватар. Например, если пользователь успешно входит в систему, для пользователя будет создан псевдоним по умолчанию, начинающийся с «u_», и пустая ссылка на аватар пользователя. .

Код для определения того, на каком шаге находится пользователь в данный момент, выглядит следующим образом:

  // 获取当前授权阶段
  public getCurrentAuthStep(): AuthStepType {
    // 切换账号登录的时候,始终返回AuthStepType.ONE
    const loginMode = this.getLoginMode();
    if (loginMode === LoginMode.SWITCH_ACCOUNT) return AuthStepType.ONE;

    // 用户身份定义非会员返回AuthStepType.ONE
    const userInfo = this.getUser();
    if (userInfo?.busiIdentity !== 'MEMBER') return AuthStepType.ONE;

    // 初次登录,未授权用户信息,返回AuthStepType.TWO
    if (userInfo.nickName.substring(0, 2) === 'u_' && !userInfo.headUrl)
      return AuthStepType.TWO;

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

3.2.2 Сценарий триггера входа пользователя

Как упоминалось ранее, «логин пользователя»Цель состоит в том, чтобы интегрировать данные о транзакциях, акциях, коллекциях и других каналах различных каналов., для апплета электронной коммерции в настоящее время обобщены сценарии, требующие входа пользователя в систему, следующие:

用户登录场景

То есть, когда пользователи входят в апплет, они могут нормально просматривать продукты.Только когда инициируются определенные конкретные действия, такие как получение купонов, добавление покупок, сбор, размещение заказов и т. д., будет оцениваться, находится ли пользователь в состоянии входа в систему.Если нет, страница входа будет перенаправлена..

Как показано ниже, пакетmustAuthметод для перехвата и перехода на страницу входа, если вы не вошли в систему:

export default class Session {
  ...
  public mustAuth({
    mustAuthStep = AuthStepType.TWO, // 传人参数,需要授权的LEVEL
  } = {}): Promise<void> {
    // 当前阶段处于会员态(2)或者会员信息态(3),执行resolve操作
    if (this.getCurrentAuthStep() >= mustAuthStep) return Promise.resolve();
    // 当前阶段处于游客态(1),跳转登录页
    Navigator.gotoPage('/login/home');
    // 执行reject操作
    return Promise.reject();
  }
}

Приведенный выше код является перехватом страницы перехода.Для всплывающего окна всплывающее окно необходимо внедритьbase-page(Общие компоненты, которые должны быть представлены на каждой странице, инкапсулируют общие методы, которые должна использовать каждая страница, такие как обработка ошибок и т. д.), найдите компонент всплывающего окна по идентификатору и вызовите его.

export default class Session {
  ...
   public mustAuth({
    mustAuthStep = AuthStepType.TWO, // 需要授权的LEVEL
    popupCompName = 'auth-flow-popup',
  } = {}): Promise<void> {
    // 当前阶段处于会员态(2)或者会员信息态(3),执行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}`);
    // 容错处理
    if (!popupComp) {
      return Promise.reject(
        new Error(
          "当前页面未找到 #auth-popup 组件,请参考 'doc/登录组件的使用方式.md'",
        ),
      );
    }
    // 调用弹窗组件方法
    popupComp.setMustAuthStep(mustAuthStep);
    popupComp.nextStep();
    // 等待授权成功回调
    return this.waitAuth();
  }
}

Каждый бизнес может использовать его черезsession.mustAuth().then(() => {...});Звоните, для улучшения опыта можно также воспользоваться декоратором@mustAuth()изменить каждое бизнес-требованиеметод класса, исходный код декоратора выглядит следующим образом:

/**
 * 登录检查装饰器,使用该装饰器的方法,会先执行授权检查,如果未授权,将跳转登录页面
 */
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 Основные компоненты

1. компонент телефонного контейнера

Поскольку пользователь должен активировать триггер, чтобы инициировать получение интерфейса авторизованного номера мобильного телефона WeChat, вам необходимо использоватьbuttonКомпонент нажмите, чтобы вызвать. Код компонента выглядит так:

// 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является чистым компонентом пользовательского интерфейса, черезtriggerEventСобытие получит данные о номере мобильного телефона и передаст их родительскому компоненту,

2. компонент пользовательского контейнера

user-containerКомпонент представляет собой чистый компонент пользовательского интерфейса для получения информации об авторизованном пользователе WeChat.<button open-type="getUserInfo" bindgetUserInfo="getUserInfo"/>способ получения. 23 февраля 2021 года команда WeChat выпустила«Вход в мини-программу, инструкции по настройке интерфейса, связанные с информацией о пользователе», добавлятьgetUserProfileИнтерфейс заменяет оригинальныйwx.getUserInfo, чтобы получить информацию об аватаре, никнейме, поле и регионе пользователя, в том числе черезbuttonКомпонент нажмите, чтобы вызвать. Разница между ними показана на рисунке ниже:

获取用户信息接口区别

До 13 апреля 2012 г. используйтеwx.getUserInfoКогда всплывающее окно авторизации всплывает, если пользователь нажимает, чтобы разрешить авторизацию, поведение пользователя будет записано.нет всплывающего окнаВместо этого результат авторизации возвращается напрямую. После 13 апреля используйтеwx.getUserProfile,Каждый раз, когда разработчик получает личную информацию пользователя через этот интерфейс, пользователю необходимо подтвердить ее, поэтому необходимо правильно сохранить авторизованный пользователем никнейм аватара, чтобы избежать повторных всплывающих окон.

3.3.2 Класс поведения

Как показано ниже,auth-flowКласс поведения в основном инкапсулирует логику взаимодействия между пользователем, апплетом и сервером.

用户行为

Во время процесса «Авторизованный вход в WeChat» апплет получает зашифрованныйencryptedDataиivданные, передавать их и носить с собойauth-tokenОтправьте его на сервер разработчика вместе, и сервер передастauth-tokenАутентификация идентифицирует этого пользователя и успешно получает его с помощью автоматического входа в систему.session_key(симметричный ключ дешифрования) параencryptedDataиivДанные симметрично расшифровываются, получается номер мобильного телефона пользователя, и номер мобильного телефонаuidBinding, в это время пользователь успешно регистрируется в качестве члена и возвращает информацию о члене в апплет.

Мини обновление программы локальноеstorageхранитсяsessionданные, на данный моментbusiIdentityЗначение изменилось сVISITобновить доMEMBER, идентификатор пользователя меняется наЧленство,Авторизация успешна.

В процессе «авторизации информации о пользователе» апплет вызываетwx.getUserProfileметод для получения пользовательских данных и объединения этих данных с переносимымиauth-tokenОтправьте его на сервер разработчика вместе, и сервер передастauth-tokenАутентификация идентифицирует пользователя, обновляет информацию о пользователе и возвращает новые данные о членстве в апплет.

Мини обновление программы локальноеstorageхранитсяsessionданные, на данный момент никнейм и аватар пользователя были обновлены, а личность пользователя изменена наИнформация об участниках, авторизация прошла успешно.

Внимательные читатели, должно быть, заметили, что аватар WeChat также был сброшен на диаграмме последовательности. Это потому чтоПосле того, как пользователь изменит аватар WeChat на терминале WeChat, ссылка на аватар WeChat, полученная из «Информации авторизованного пользователя», станет недействительной., поэтому разработчик должен сохранить аватар после получения информации о пользователе самостоятельно, чтобы избежать нештатной ситуации после того, как URL-адрес аватара WeChat недействителен.

3.3.3 Общие компоненты

Общие компоненты представляют собой вторичную инкапсуляцию базовых компонентов и классов поведения, в основном для предоставления бизнес-уровню двух возможностей входа через всплывающее окно и входа через страницу.

4. Резюме

Мы абстрагируем возможность входа пользователя в систему от бизнес-уровня и единообразно инкапсулируем ее вserviceслой для легкого повторного использования. В этой статье в основном говорится оserviceСтруктура уровня не слишком усложняет логическую реализацию бизнес-уровня. В следующей таблице кратко описывается внешняя и внутренняя логическая реализация всего набора «автоматического входа в систему» ​​и «входа пользователя» на примере апплета.

Деловая сцена Восприятие пользователя Логика обработки интерфейса Логика серверной обработки Дополнительные инструкции
Поиск кода сканирования и другие методывойти в апплет никто 1. Оценка: кэшировал ли текущий апплет статус входа в систему.auth-tokenи использоватьwx.checkSeesionПроверьте, не истек ли срок действия статуса входа текущего пользователя в апплете, и выполните шаг 2 после истечения срока действия;
2. Используйтеwx.loginПолучить информацию для аутентификации, запросить серверную частьwxLoginИнтерфейс получает идентификатор пользователя и статус входа в систему, привязанный по умолчанию для аутентификации апплета WeChat.auth-token.
1. Проанализируйте зашифрованную информацию WeChat, чтобы получить аутентификациюopenidиunionId;
2. НайдитеopenidБыл ли связан соответствующий пользователь, если привязка возвращается напрямую и генерирует для него соответствующий статус входа в системуauth-token;
3. Новые пользователиopenidАвтоматически генерировать для него идентификатор пользователяuid(см. Дополнительное примечание справа).
Какие,Совокупный корневой идентификатор существуетunionId&& содержит информацию о пользователе: существующий совокупный пользователь root, соответствующийexUidсопоставить непосредственно с текущимuidВниз;
Нет,Совокупный корневой идентификатор существуетunionId&& нет информации о пользователе:в соответствии сunionIdСоздайте соответствующую учетную запись, но сopneidсоответствующийuidпоследовательный;
от,Совокупный корневой идентификатор не существует: Непосредственно соответствуетopenidинициализироватьuid.
собирать,добавить,разместить заказ,купонждать прыжок с перехватом 1. Решение: Текущая идентификация пользователя находится в гостевом состоянии, и перейдите на страницу входа. Соответствующий серверный интерфейс службы домена может быть перенесен в соответствии с запросом.auth-tokenВыполните аутентификацию, чтобы определить, есть ли у пользователя полномочия на выполнение операций. -
Логин пользователяилисменить аккаунт выберите:
1. Авторизуйте номер мобильного телефона WeChat для входа в систему;
2. Введите номер своего мобильного телефона и используйте проверочный код/пароль для входа.
1. Пользователь выбирает авторизацию номера мобильного телефона для входа в систему, и серверная часть будет входить в систему в соответствии с последним автоматическим входом в систему.sesssionKeyРасшифровка, если расшифровка не удалась, вам нужно снова пройти автоматический вход в систему и позволить клиенту повторить попытку.
2. Пользователь решает пройтиВход с кодом подтвержденияКогда вам нужно обратить внимание на устаревание кода проверки и механизм повторных попыток, а также иметь логику обработки ошибок;
3. Выбор пользователяпароль логинКогда учетная запись не зарегистрирована или пароль учетной записи не равен, требуется независимая регистрация кода проверки логического перехода или восстановление пароля.
4.Все три из вышеперечисленных должны быть выполненыauth-tokenАутентификация
1. Согласноauth-tokenПолучить текущую учетную запись базовой аутентификации каналаopenid-unionId-uid;
2,Авторизованный номер телефона для входаЕсли вам нужно сначала расшифровать номер мобильного телефона, в настоящее время проверка не требуется.Введите свой номер телефона для входаКогда вам нужно проверить «пароль» или «код подтверждения», проверка пароля перехватит сцену, в которой учетная запись не существует или пароль неверен;
3. По номеру мобильного телефона определить, существует ли соответствующая учетная запись канала номера мобильного телефона под текущим корнем агрегации (см. дополнительное описание процесса привязки справа).
4. Вернуть результат входа.
Какие,Номер телефона уже существует: преобразовать существующего пользователяexUidПривязать к текущей учетной записи;
Нет,Мобильный номер не существует && личность пользователя является туристом: Переписка мобильных телефонов с туристамиuidсвязывать
от,Мобильный номер не существует && личность пользователя является участником: создать новый номер телефона дляnewUid, и привяжите текущую учетную запись канала openid кnewUid.

Уровень автора ограничен, подскажите~