Serie de miniprogramas de desarrollo de aplicaciones uni: inicio de sesión de WeChat

¿Qué es el inicio de sesión de WeChat?

El documento oficial dice: Los Mini Programas pueden obtener fácilmente la identidad de usuario proporcionada por WeChat a través de la capacidad de inicio de sesión oficial proporcionada por WeChat y establecer rápidamente un sistema de usuario dentro del Mini Programa. En otras palabras, permita que la identificación de usuario del usuario en nuestro applet se asocie con la identificación abierta de WeChat del usuario. De esta manera, cuando un usuario visita, podemos obtener el open_id del usuario para conocer la identificación del usuario en nuestra plataforma. De esta forma, el usuario puede iniciar sesión en su cuenta sin ingresar la contraseña de la cuenta.

proceso de inicio de sesión

También se proporciona un diagrama de secuencia en la documentación oficial de todo el proceso de inicio de sesión, de la siguiente manera: Lo que debe explicarse es que el servidor del desarrollador es nuestro servicio de back-end. Por lo tanto, para realizar el inicio de sesión rápido de WeChat del usuario en el applet de WeChat, se requiere la cooperación de los extremos frontal y posterior (excepto para el desarrollo de pila completa). El proceso principal completado en el lado frontal son los cuatro pasos 1, 2, 6 y 7 en la figura.

Implementación

Con el diagrama de secuencia anterior, en realidad es relativamente simple para nosotros completar la lógica de inicio de sesión, simplemente siga el proceso. El primer paso es, por supuesto, tener un proyecto de subprograma WeChat. El autor usó el proyecto inicializado por uni-app. Los amigos que no hayan generado el proyecto pueden pasar a mi otro blog: serie de subprogramas de desarrollo uni-app -- proyecto para
construir

¿Cuándo activar el inicio de sesión del usuario?

¿Cuándo activar el inicio de sesión del usuario? Las diferentes aplicaciones en este lugar tienen diferentes requisitos y diseños. En opinión del autor, debido a que el proceso de inicio de sesión en realidad es silencioso, el usuario no es consciente de ello y no implica la obtención de datos privados del usuario, por lo que es mejor iniciar sesión de inmediato para generar un estado de sesión de usuario cuando el usuario directamente accede a ella. Esto nos permite analizar los datos de los visitantes también. En el proyecto uni-app, hay un componente raíz App.vue, podemos elegir hacer un procesamiento lógico de inicio de sesión en la función de ciclo de vida onLaunch aquí. El código del autor es el siguiente:

<script>
export default {
  onLaunch: function() {
    // 从storage获取登录信息,没有则需要登录
    let tokenInfo = uni.getStorageSync("tokenInfo");
    let hasValidToken = false;
    if (tokenInfo) {
      let time = new Date().valueOf();
      // 存储时间小于token失效时间,才是有效token, 否则重新授权
      hasValidToken = time - tokenInfo.timestamp < 3600 * 24 * 1000;
    }
    if (!hasValidToken) {
      // 调用小程序登录api
      uni.login({
        provider: "weixin",
        success: (wxInfo) => {
          // 获取到code后,提交给服务端
          this.$api.post('/wxa/login', {
            code: wxInfo.code,
          }).then((res) => {
            // 存储获取到的token
            uni.setStorage({
              key: 'tokenInfo',
              data: {
                token: res.token,
                timestamp: new Date().valueOf()
              }
            })
          })
        },
      });
    }
  },
  onShow: function() {
    console.log('App Show')
  },
  onHide: function() {
    console.log('App Hide')
  }
}
</script>

El código anterior ya contiene los pasos 1, 2 y 6 en el diagrama de secuencia. Hay algunos lugares que necesitan ser explicados:

  1. ¿Por qué usar almacenamiento?

storage 是官方提供的 api, 用于将数据存储在本地缓存中指定的 key 中。除非用户主动删除或因存储空间原因被系统清理,否则数据都一直可用。单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB。所以我们如果把 token 存储到 storage 里后,可以减少对 wx.login 接口以及后端接口的频繁调用。

  1. 为何要判断 token 是否失效?

笔者的思路是存储 token 时顺便记录下时间戳。获取 token 时,会拿当前时间戳减去存储时的时间戳得到存储时间,然后判断是否超过 30 天(当然这个时间可以和后端协商)。如果超过,则为失效,那么则需要重新去登录。有的人觉得没必要做这一步,如果 token 失效,会在调用其他接口时得到一个类似 401 之类的错误码,然后再去重新登录就行。当然这也是可以的,只是笔者觉得在这里处理的话,逻辑更加集中,且体验相对好一些。

如何携带登录态?

当我们本地获取了 token,则表示登录成功,接下来是在其他请求中携带上 token,这样后端才知道是哪个用户的请求。我们当然不能在每个请求中去加这个逻辑,这样工程量很大。所以,最好先对 wx.request 进行一次封装,然后所有的请求走咱们封装后的方法。笔者代码如下:

// 该处配置为后端接口地址
const defaultHost = "http://api-server.com";

const errorMsg = (response) => {
  let error = {};
  if (response.statusCode) {
    error.code = response.statusCode;
    switch (response.statusCode) {
      case 400:
        error.msg = "错误请求";
        break;
      case 401:
        error.msg = "未授权,请重新登录";
        break;
      case 403:
        error.msg = "拒绝访问";
        break;
      case 404:
        error.msg = "请求错误,未找到该资源";
        break;
      case 405:
        error.msg = "请求方法未允许";
        break;
      case 408:
        error.msg = "请求超时";
        break;
      case 500:
        error.msg = "服务器端出错";
        break;
      case 501:
        error.msg = "网络未实现";
        break;
      case 502:
        error.msg = "网络错误";
        break;
      case 503:
        error.msg = "服务不可用";
        break;
      case 504:
        error.msg = "网络超时";
        break;
      case 505:
        error.msg = "http版本不支持该请求";
        break;
      default:
        error.msg = `连接错误${response.statusCode}`;
    }
  } else {
    error.code = 10010;
    error.msg = "连接到服务器失败";
  }
  return error;
};

function request(path, method, data, setting) {
  const tokenInfo = uni.getStorageSync("tokenInfo");
  const host = setting ? setting.host || defaultHost : defaultHost;
  const token = setting ? setting.token || tokenInfo.token : tokenInfo.token;
  return new Promise((resolve, reject) => {
    uni.request({
      url: host + path,
      method: method,
      data: data,
      header: {
        Authorization: "Bearer " + token,
      },
      success: (res) => {
        // 状态码非200的处理
        if (res.statusCode >= 400) {
          const error = errorMsg(res);
          uni.showToast({
            title: error.msg,
            icon: "none",
          });
          reject(errorMsg(res));
          // errorCallback(errorMsg(res))
        } else if (res.data.code) {
          uni.showToast({
            title: res.data.msg,
            icon: "none",
          });
          // reject(errorMsg(res.data.msg))
          // errorCallback(res.data)
        } else {
          resolve(res.data);
          // successCallback(res.data)
        }
      },
    });
  });
}

export default {
  get: (path, data, otherData) => {
    return request(path, "get", data, otherData);
  },
  post: (path, data, otherData) => {
    return request(path, "post", data, otherData);
  },
  request: request,
};

记住上述代码也有几个地方需要注意:

  1. defaultHost 是后端接口的域名部分,如果是有分测试环境真实环境,那么该处最好根据环境判断一下;
  2. 笔者是按照 jwt 规范在 header 中添加的 token 信息,这里的规则也是可以和后端进行协商;
  3. 关于错误码的判断,笔者判断如果后端返回了自定义的错误码时,返回 0 为正常响应,不为 0 则都算异常。这里需要根据实际情况进行调整。

封装了请求后,我们就可以直接调用需要登录态才能访问的接口了。比如获取用户信息:

<template>
  <div class="my">
    <div>用户ID:{{userInfo.id}}</div>
    <div>用户昵称:{{userInfo.username}}</div>
    <div>用户openId:{{userInfo.openId}}</div>
  </div>
</template>

<script setup>
  import { ref } from "vue";
  import request from "@/common/request.js";

  const userInfo = ref({});

  request.get("/user/info").then((res) => {
    userInfo.value = res;
  });
</script>
<style lang="scss" scoped>
  .my {
    width: 100%;
  }
</style>

至此,登录功能完成。

后记

本次任务只是完成了用户登录,如果想获取用户昵称头像甚至手机号,那还需要申请用户授权,比较复杂,笔者将在下篇博客中详细介绍。

关于作者

Graduado de una especialización en informática, más de 8 años de experiencia en desarrollo web y ha estado profundamente involucrado en las pilas de tecnología Vue2 y Vue3 durante muchos años. Con una gran experiencia en el desarrollo de pila completa, el árbol de habilidades cubre todo el proceso de enlace, desde la construcción de ingeniería de front-end hasta la implementación y el lanzamiento. Manteniéndonos al día con las tendencias tecnológicas, hemos estado prestando atención a varias tendencias tecnológicas emergentes y realizando activamente exploraciones prácticas, buscando una experiencia de desarrollo elegante, una eficiencia de desarrollo extrema y una calidad de desarrollo de alto nivel.

Bienvenido a criticar y corregir, o comuníquese conmigo para discutir la tecnología front-end. El código fuente no se ha hecho público, por favor contácteme para enviarlo en privado.

Contáctame: imwty2023 (WeChat)

Dirección original del blog: serie de miniprogramas de desarrollo de aplicaciones uni: inicio de sesión de WeChat | imwty

Supongo que te gusta

Origin juejin.im/post/7210020384044580925
Recomendado
Clasificación