vue微信授权解决方案(第三次优化)

16,705 阅读6分钟

github:vue-wechat-auth

之前是自己太年轻,写什么【最终解决方案】。这一次的项目vue移动端电商项目,做了很多的优化。大家都知道授权需要每次都要发布到线上,本地的需要代理,这让我们很头疼。后面会介绍一个本地直接授权的方式,真的超级香。

时隔几年,第三次升级我的微信授权,每一次思路都更加清晰,当我的知识越来越广,越来越深,我相信会有第四次,第五次。。。

另外也优化:

  • 微信分享
  • keep-alive返回到上次浏览的位置
  • vue-router 所有页面携带参数
  • ...

后续会持续分享,接下来首先优化的就是授权逻辑的优化。

场景

整个项目无论什么页面进入都需要进行授权,一般微信公众号H5项目这一点都是需要做到

接下来我们开始吧,先克隆安装依赖,不要着急启动,先把准备工作做好。

// 克隆项目
git clone https://github.com/sunniejs/vue-wechat-auth.git
//安装依赖
npm install 

实现本地微信授权

1.工具

实现本地开发授权,你需要使用微信开发者工具,网页是没有办法直接本地拿到授权的。

2.将auth.html部署到服务器上

为什么要部署auth.html呢?

实现微信授权,微信官方要你填写一个授权回到页面域名,授权的地址必须是这个域名,那localhost显然是不可以了,那怎么办呢?

我们跳微信授权地址的时候redirect_uri 携带的地址为符合要求的微信回调域名,比如www.abc.com/auth.html?b… 回到这个页面的时候,我们再跳转到本地http://localhost:9018/#/?code=23456789**带着我们想要的code 就搞定了!那么开始吧。

1. 前往微信公众平台->接口权限->网页授权获取用户基本信息->修改,填写授权回调页面域名,例如www.abc.com

2. 微信要求将MP_verify_xxx.txt文件放到服务器下。按照提示操作就可以了。

3. 部署auth.html(在github项目的根目录下) ,相同的,将 auth.html 上传至填写域名或路径指向的web服务器(或虚拟主机)的目录( 例如 :**www.abc.com/auth.html**…

www.abc.com域名下的服务器上部署auth.html,不一定是根目录,例如:www.abc.com/xxx/auth.ht…        

这里我们用auth.html是根据 GetWeixinCode 进行修改的,修复了一些bug,感谢作者

  • 携带的参数在授权完之后没能全部带回来。
  • hash回调url错误问题

3.设置相关变量

在开发之前你要首先在下面三个文件设置两个变量,如果你已经启动项目,设置后需要重启

.env.development

.env.staging

.env.production

VUE_APP_WECHAT_APPID是你的appid,在.env.[环境] 文件中设置

VUE_APP_WECHAT_AUTH_URL是你的auth.html 访问地址。在.env.[环境] 文件中设置

设置好了之后我们就可以通过 process.env.  使用了

4.实现微信授权相关方法

文件路径:src/plugins/wechatAuth.js,主要是先微信跳转地址拼接,获取地址参数等。

微信授权相关方法封装这里引用的是[vue-wechat-login],做了简单的修改,直接在路由钩子文件permission.js使用。

在permission.js去调用一些方法比如: wechatAuth.returnFromWechat(to.fullPath);

5.permission.js 路由守卫

src/permission.js 里实现了主要的逻辑。

首先我们现设置授权白名单whiteList,授权失败,或者其他错误进入404页面。

  const whiteList = ['/404']  router.beforeEach(async (to, from, next) => {   // 在白名单,直接进入   if (whiteList.indexOf(to.path) !== -1) {      return next()    }
    // ....
  })

接下来我们设置一个loginStatus,用来表示登录的状态 ,0代表没有登录,那么就需要跳转到微信授权地址了。

      // 设置回调地址,本地和线上不同  
     wechatAuth.redirect_uri = processUrl()
     await store.dispatch('user/setLoginStatus', 1)
      // 跳转完整的授权地址
      window.location.href = wechatAuth.authUrl

wechatAuth.authUrl 地址 https://open.weixin.qq.com/connect/oauth2/authorize...的redirect_uri 调用 processUrl方法,根据环境不同返回不同的地址。前面我们提到授权的回到地址必须是微信公众号设置的授权页面域名,所以这里分两种情况

  • 本地环境返回授权的回调地址:

    // 本地环境换通过auth.html拿code
    if (process.env.NODE_ENV === "development") { return https://test.top1buyer.com/auth.html?backUrl=${window.location.href}; }

 其中 process.env.VUE_APP_WECHAT_AUTH_URL 就是中间授权页面的网址。backUrl后面跟的是你本地开发的地址。processUrl() 返回 www.abc.com/auth.html?b…

  • 线上环境返回的是正常的微信授权地址:

    const url = window.location.href;
    // 解决多次登录url添加重复的code与state问题 const urlParams = qs.parse(url.split("?")[1]); let redirectUrl = url; if (urlParams.code && urlParams.state) {
    delete urlParams.code;
    delete urlParams.state;
    const query = qs.stringify(urlParams); if (query.length) {
    redirectUrl = ${url.split("?")[0]}?${query}; } else { redirectUrl = ${url.split("?")[0]};
    }
    } return redirectUrl;

processUrl() 返回 **线上你的项目地址,**不用中间页跳转。只要保证你的项目域名,(比如:www.abc.com/wxapp/ ),的域名在微信公众号设置的网页授权域名列表里就ok了。不跳转中间页会提升用户体验。

启动项目

必要的参数设置好就可以启动了

// 启动
npm run serve 

同意之后就看到code值了

到此主要的流程就结束了。

注意:当授权成功后需要通过code换取token,因为并没有对接后台,所以这里我注释掉了

接下来操作在vuex中进行,用户根据需求对接后台接口即可。

/src/store/modules/user.js

比如这里我需要通过code换区用户信息,存储用户信息和token

 const actions = { 
   // 登录相关,通过code获取token和用户信息,用户根据自己的需求对接后台 
   loginWechatAuth({commit}, code) {     
   const data = {        code: code      } 
   return new Promise((resolve, reject) => {   
     loginByCode(data)
          .then(res => {
            // 存用户信息,token
          commit('SET_USERINFO', saveUserInfo(res.data.user))
            commit('SET_TOKEN', saveToken(res.data.token))
            resolve(res)
          })
          .catch(error => {
            reject(error)
          })
      })
    }, 
} 

src/utils/request.js

axios数据请求封装,请根据用户需求自行修改

src/utils/cache.js文件用户来缓存数据

 import cookies from 'js-cookie'import storage from 'good-storage'const LoginStatusKey = 'Login-Status' // 登录态 0未授权未登录 1授权未登录 2 登陆成功const TokenKey = 'Access-Token' // tokenconst UserInfoKey = 'User-Info' // 用户信息 {} {...}// 获取登录状态export function loadLoginStatus() {  return cookies.get(LoginStatusKey) || 0}// 保持登录状态export function saveLoginStatus(status) {  cookies.set(LoginStatusKey, status, {expires: 7})  return status}// 删除登录状态export function removeLoginStatus() {  cookies.remove(LoginStatusKey)  return ''}// 获取tokenexport function loadToken() {  return storage.get(TokenKey, '')}// 保存tokenexport function saveToken(token) {  storage.set(TokenKey, token)  return token}// 删除tokenexport function removeToken() {  storage.remove(TokenKey)  return ''}// 获取用户信息export function loadUserInfo() {  return storage.get(UserInfoKey, {})}// 保存用户信息export function saveUserInfo(userInfo) {  storage.set(UserInfoKey, userInfo)  return userInfo}// 删除用户信息export function removeUserInfo() {  storage.remove(UserInfoKey)  return {}}

项目地址

github:vue-wechat-auth

另外,项目架构介绍请看[ vue-h5-template]基于vue-cli4.0+webpack 4+vant ui + sass+ rem适配方案+axios封装。如果你只需要授权逻辑,只要把涉及到的相关文件放到你的项目下就可以。

常见问题

  • 上线后一直循环跳转,清除缓存,注释掉 src/utils/request.js 里的 location.reload() 调试

关于我

如果您遇到了问题可以给我提 issues 

获取更多技术相关文章,关注公众号”前端女塾“。

回复‘前端’,即可加入”前端仙女群“

您也可以扫描添加下方的微信并备注 Sol 加前端交流群,交流学习。

如果对你有帮助送我一颗小星星,你的star是我前进的动力(づ ̄3 ̄)づ╭❤~