【vue3+vite应用从0到1】4.登录(微信公众号下)

662 阅读4分钟

简介:微信授权登录判断 axios AccessToken

在这之前默认对axios的封装,微信公众号的用户认证授权也是了解的。 不了解的可前往:

我使用微信公众号的用户登录和后端换取自己应用的accss_token然后将access_token本地存储以及放在请求头上。【注意:自己应用的Access_token和微信授权返回的Access_token不是同一个

登录流程

前端登录流程很简单

微信公众号下登录,就是将登录页面换成了微信登录的承接页,用来跳转微信授权

graph TD
检查是否登录 --> 未登录 --> 登录页面 --> 登录 --> 获取token --> 本地存储 --> 发请求放到headers中--> 完成

Code it

我们只要关心以下几个模块逻辑就好了

Module1:微信承接页

微信承接页是有两个作用:

  1. 从这里唤起授权。
  2. 作为微信授权后的回调页面

逻辑很简单,判断当前链接是否带着code, 如果带着就表示是从微信授权后的回调,如果没有则表示需要唤起回调

import { auth, AuthType } from "@/utils/auth";
import { getURLParam } from "@/utils/common";
import { useRouter } from "vue-router";
const router = useRouter();
const code = getURLParam(location.href, "code");
if (code) {
  auth.login(AuthType.wechat, code).then(() => {
    router.push("/");
  });
} else {
  auth.wechat.gotoAuthPage();
}

Module2:授权的帮助类

这个类是需要进行登录授权的统一封装,这样代码逻辑会清晰些

扩展性:这并不是脱裤子放屁

你会发现我定义了AuthType以及单独的wechatHandler,在auth中的login,会根据传入的AuthType去调用具体的login,因为我想着我后面应该会采取手机号验证的方式来进行登录,为了方便后续扩展,我就这样定义了。 这样我后面扩展手机登录,我只需要定义一个 phoneHandler,并实现login方法即可,外部调用也只需要调用auth.login(AuthType.phone,arg...)

这个帮助类的具体逻辑也很简单,登录方法前期先判断是否已经登录过了,登录过了则直接resolve(),如果没有则去调取后端接口,后端接口返回 access_token ,前端在localStorage中存储。

// 登录认证相关工具类
import { getStorage, setStorage, removeStorage } from "./storage";
import { getWechatAuthUrl } from "@/apis/wechatAuth.ts";
import { loginByWechat } from "@/apis/auth";
const accessTokenStorageKey = "ACCESS_TOKEN";
const wechatHandler = {
  gotoAuthPage() {
    getWechatAuthUrl().then((data) => {
      location.href = data;
    });
  },
  login(code: string) {
    return loginByWechat(code);
  },
};

// 给后续需要接入其他认证方式留下可扩展项
export enum AuthType {
  wechat = "wechat",
}

export const auth = {
  wechat:wechatHandler,
  login(type: AuthType, args: any, force: boolean = false): Promise<void> {
    return new Promise((resolve, reject) => {
      const isLogin = auth.isLogin();
      console.log(isLogin &&  !force);
      if (isLogin && !force) {
        resolve();
      } else {
        if (auth[type]) {
          auth[type].login
            .call(auth[type], args)
            .then((res) => {
              setStorage(accessTokenStorageKey, res["access_token"]);
              resolve();
            })
            .catch((err) => {
              reject(err);
            });
        } else {
          reject("不支持当前登录方式");
        }
      }
    });
  },
  isLogin() {
    return !!getStorage(accessTokenStorageKey);
  },
  logout() {
    removeStorage(accessTokenStorageKey);
  },
};

Module3: axios中取值放在headers

这是最简单的一步了 在请求的拦截器中,给headers中加入accss_token

题外话:Bearer是什么?

一个标准定式。“Bearer”令牌是OAuth 2.0协议的一部分,而OAuth 2.0是目前最广泛使用的授权框架之一。使用“Bearer”标识符可以标明后面的令牌是一个Bearer Token,即无需额外证明身份,仅凭令牌即可访问资源。这是一种简洁但有效的方式来表达这一概念。使用“Bearer”架构发送JWT是遵循现有标准、简化授权流程的一种方式。这既符合OAuth 2.0协议的规定,也提供了一种清晰、安全且灵活的机制,以处理Web请求的授权。

const accessTokenStorageKey = "ACCESS_TOKEN";
// 添加请求拦截器
instance.interceptors.request.use(
  function (config) {
    config.headers.Authorization = `Bearer ${getStorage(accessTokenStorageKey)}`;
    return config;
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
);

image.png


完结撒花 ❀❀❀❀❀❀❀

我的其他专栏传送门