欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue3項目中優(yōu)雅實現(xiàn)微信授權登錄的方法

 更新時間:2021年09月09日 09:39:46   作者:imwty  
用戶在微信端中訪問第三方網(wǎng)頁,可以通過微信網(wǎng)頁授權機制獲取用戶的基本信息,進而實現(xiàn)所需要的業(yè)務邏輯,這篇文章主要給大家介紹了關于Vue3項目中優(yōu)雅實現(xiàn)微信授權登錄的相關資料,需要的朋友可以參考下

前言

微信授權登錄是做微信公眾號開發(fā)一直繞不開的話題,而且整個授權登錄流程的實現(xiàn),是需要前后端配合一起完成的。在過去前后端還未分離的年代,也許我們前端并不需要太過關心授權的具體實現(xiàn)。然而現(xiàn)在都2021年了,前后端分離的架構大行其道,如何在前后端分離的情況下實現(xiàn)微信授權登錄就成了今天要探討的重點問題。

準備

首先,我們還是需要先梳理下微信授權整個流程是怎樣的,這里我就直接將官方文檔搬來:

如果用戶在微信客戶端中訪問第三方網(wǎng)頁,公眾號可以通過微信網(wǎng)頁授權機制,來獲取用戶基本信息,進而實現(xiàn)業(yè)務邏輯。

...

關于網(wǎng)頁授權的兩種scope的區(qū)別說明

1、以snsapi_base為scope發(fā)起的網(wǎng)頁授權,是用來獲取進入頁面的用戶的openid的,并且是靜默授權并自動跳轉到回調(diào)頁的。用戶感知的就是直接進入了回調(diào)頁(往往是業(yè)務頁面)

2、以snsapi_userinfo為scope發(fā)起的網(wǎng)頁授權,是用來獲取用戶的基本信息的。但這種授權需要用戶手動同意,并且由于用戶同意過,所以無須關注,就可在授權后獲取該用戶的基本信息。

...

具體而言,網(wǎng)頁授權流程分為四步:

1、引導用戶進入授權頁面同意授權,獲取code

2、通過code換取網(wǎng)頁授權access_token(與基礎支持中的access_token不同)

3、如果需要,開發(fā)者可以刷新網(wǎng)頁授權access_token,避免過期

4、通過網(wǎng)頁授權access_token和openid獲取用戶基本信息(支持UnionID機制)

這里附上微信公眾號開發(fā)之微信授權的官方文檔。

以上是筆者提煉出來的比較關鍵的幾點信息,當然還有更多的說明,希望新手讀者們還是先認真看完官方文檔。

這里我再補充說明下,以上流程的4個步驟中,除了第一步以外,另外三步都是需要在服務器端去完成的。前端要做的核心其實是怎么進行用戶登錄狀態(tài)的檢查判斷和登錄狀態(tài)的維護。

實現(xiàn)思路

大家都知道,Vue是前后端分離技術方案下的產(chǎn)物,它是一個純前端應用(服務端渲染除外)。通常我們是需要在用戶打開頁面,執(zhí)行到頁面的js腳本時,我們再異步去請求服務端數(shù)據(jù),再進行相關邏輯的處理和判斷。我們要實現(xiàn)微信授權登錄的前提是,需要先判斷用戶是否需要登錄(cookie或者token)。當用戶未登錄時,才需要走授權登錄流程,當授權登錄成功后,我們也需要在前端記錄好登錄狀態(tài),以方便在頁面切換時,不用再次觸發(fā)授權登錄。再通過分析可知,前端其實能做的就是獲取微信服務器給我們的code,再將code給我們的后端,讓后端完成后續(xù)步驟拿到用戶信息后生成用戶。那么整個過程我再梳理如下:

  1. (前端)檢查用戶是否登錄;
  2. (前端)如果未登錄,引導用戶進入授權頁面同意授權,獲取code
  3. (前端)將獲取到的code提交給后端
  4. (后端)通過code換取用戶憑證openid
  5. (后端)通過openid檢查用戶是否存在,是否需要注冊新用戶,并獲取用戶id
  6. (后端)返回用戶信息;
  7. (前端)記錄用戶登錄狀態(tài),跳回登錄前頁面;

這個過程,我畫了個圖,如下:

上代碼

根據(jù)以上思路,現(xiàn)在開始編碼環(huán)節(jié)。筆者采用的是Vue3,Vue2的開發(fā)者還請根據(jù)情況做適當調(diào)整。
為了方便喚起用戶授權登錄邏輯,筆者打算將授權登錄封住為一個login頁面,這樣做的好處是我們在任何判斷到需要登錄的地方直接通過Vue Router的push方法跳轉到登錄頁面即可。

通常情況下,我們的應用并不是所有頁面都需要登錄后才能訪問,只有在訪問特定頁面時候,才需要用戶登錄,那么我們就需要標識哪些頁面需要進行登錄鑒權。這里我們可以利用Vue Router的meta屬性來進行標識,官方文檔對meta解釋如下:

有時,你可能希望將任意信息附加到路由上,如過渡名稱、誰可以訪問路由等。這些事情可以通過接收屬性對象的meta屬性來實現(xiàn),并且它可以在路由地址和導航守衛(wèi)上都被訪問到。

剛好Vue Router官方就有示例,如下:

const routes = [
  {
    path: '/posts',
    component: PostsLayout,
    children: [
      {
        path: 'new',
        component: PostsNew,
        // 需要登錄后才能訪問的頁面
        meta: { requiresAuth: true }
      },
      {
        path: ':id',
        component: PostsDetail,
        // 任何人都可訪問的頁面
        meta: { requiresAuth: false }
      }
    ]
  }
]

接下來我們就可以在Vue Router的全局守衛(wèi)beforeEach中獲取到這個元信息從而做登錄跳轉了

router.beforeEach((to, from) => {
  // 而不是去檢查每條路由記錄
  // to.matched.some(record => record.meta.requiresAuth)
  if (to.meta.requiresAuth && !userStore.isLogin) {
    // 此路由需要授權,請檢查是否已登錄
    // 如果沒有,則重定向到登錄頁面
    return {
      path: '/login',
      // 保存我們所在的位置,以便以后再來
      query: { redirect: to.fullPath },
    }
  }
})

需要補充說明的是,userStore.isLogin的實現(xiàn)。這里和我們實際采用的登錄態(tài)維護方案有關,如果是采用token方式的話,那就是檢查token是否已經(jīng)存在。筆者采用了vuex作為來保存token,然后借助插件來將Store中的數(shù)據(jù)持久化到localStorage。

接下來我們來看具體的實現(xiàn):

login.vue: 登錄組件

<template>
  <div class="login"></div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'

import { jump2Auth, getUserInfo } from '@/hooks/useWechatAuth'
import { userStore } from '@/store/modules/user'
import { redirectTo, getRouteQuery } from '@/hooks/usePage'

export default defineComponent({
  name: 'Login',
  setup() {
    let code = getRouteQuery().code as string
    // 3.如果有code,則已經(jīng)授權
    if (code) {
      getUserInfo(code as string).then((res: any) => {
        // 記錄token
        userStore.saveToken(res.access_token)
        const redirect = userStore.userState.landPageRoute || '/'
        // 跳轉到授權前訪問的頁面
        redirectTo(redirect)
      })
    } else {
      // 1.記錄上一個頁面的地址
      const { redirect } = getRouteQuery()
      if (redirect) {
        userStore.setLandPage(redirect as string)
      }
      // 2.跳轉授權
      const callbackUrl = window.location.origin + window.location.pathname
      jump2Auth(callbackUrl)
    }
  },
})
</script>

可以看到,login頁面其實并沒有什么內(nèi)容,跳轉到該頁面后,我們會直接重定向到微信授權的頁面,授權回調(diào)回來也會回到該頁面,此時我們再通過獲取路由參數(shù)的方式獲取code參數(shù)。

@/hooks/usePage.ts: 該文件主要是封裝了router相關的常用方法

import router from '@/router'
import { cloneDeep } from 'lodash'
import { toRaw } from 'vue'

/**
 * 重定向
 * @param path 路徑
 */
export function redirectTo(path: string) {
  const { replace } = router
  replace({
    path,
  })
}

/**
 * 獲取路由上query參數(shù)
 */
export function getRouteQuery() {
  const { currentRoute } = router
  const { query } = currentRoute.value
  return cloneDeep(query)
}

@/hooks/useWechatAuth.ts:該文件封裝了微信授權與后端交互的請求

import { useAxios } from '@/hooks/useAxios'

/**
 * 獲取微信授權的跳轉地址
 * @param callbackUrl 授權后回調(diào)鏈接
 * @returns
 */
export function jump2Auth(callbackUrl: string) {
  useAxios({
    url: '/api/wechat/auth',
    params: {
      redirect_url: callbackUrl,
    },
  }).then((authUrl: any) => {
    if (process.env.NODE_ENV === 'development') {
      window.location.href = callbackUrl + '?code=test'
    } else {
      window.location.href = authUrl
    }
  })
}

/**
 * 提交code進行登錄
 * @param code
 * @returns
 */
export async function getUserInfo(code: string) {
  const userInfo = await useAxios({
    method: 'POST',
    url: '/api/wechat/auth',
    params: {
      code,
    },
  })
  return userInfo
}

@/store/modules/user.ts: 全局狀態(tài)存儲,主要是記錄token和登錄前訪問頁面

import { Module, VuexModule, Mutation, getModule, Action } from 'vuex-module-decorators'
import store from '@/store'
import { initialUnencryptedStorage } from '../globals'

interface UserState {
  token: string
  landPageRoute: string
}

const NAME = 'user'
// name: 模塊名字
// namespaced 表示開啟命名空間
// dynamic設置為true時,表示創(chuàng)建動態(tài)模塊,運行時將模塊注冊到存儲中
// preserveState 如果數(shù)據(jù)有持久化,該變量為true時可以從storage中拿取初始值
@Module({
  namespaced: true,
  name: NAME,
  dynamic: true,
  store,
  preserveState: Boolean(initialUnencryptedStorage[NAME]),
})
export class User extends VuexModule {
  userState: UserState = {
    token: '',
    /** 登錄前訪問頁面 */
    landPageRoute: '',
  }

  get isLogin(): boolean {
    return !!this.userState.token
  }

 
  @Mutation
  saveToken(token: string): void {
    this.userState.token = token
  }

  @Mutation
  setLandPage(route: string): void {
    this.userState.landPageRoute = route
  }
}

export const userStore = getModule<User>(User)

筆者借助vuex-persistedstate插件將store中數(shù)據(jù)存儲到了localStorage,這樣做的好處是用戶關閉頁面后,再次訪問,即不用重新觸發(fā)微信授權流程,大大優(yōu)化了用戶體驗。

總結

不得不說,Vue3在代碼抽象和復用這塊上,寫起來著實舒服很多,希望大家也也嘗試著按照官方實踐那樣,多將邏輯代碼解耦抽離,生成一個個的hook,這樣代碼就顯得優(yōu)雅多啦。該方案經(jīng)過筆者嘗試論證,不論是代碼整潔優(yōu)雅程度,還是業(yè)務需求的實現(xiàn)上,都幾乎完美(請容我裝一波b)。當然,這里可能存在我沒發(fā)現(xiàn)的bug或者痛點,畢竟從來沒有十全十美的架構嘛,這里也歡迎看官大佬們和我交流探討,提供更好的方案和想法。

到此這篇關于Vue3項目中優(yōu)雅實現(xiàn)微信授權登錄的文章就介紹到這了,更多相關Vue3微信授權登錄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 如何寫一個 Vue3 的自定義指令

    如何寫一個 Vue3 的自定義指令

    這篇文章主要介紹了如何寫一個 Vue3 的自定義指令,如果我們想在 Vue.js 的項目中實現(xiàn)圖片懶加載,那么用自定義指令就再合適不過了,那么接下來就讓我手把手帶你用 Vue3 去實現(xiàn)一個圖片懶加載的自定義指令 v-lazy,需要的朋友可以參考一下
    2022-01-01
  • Vue2.0中集成UEditor富文本編輯器的方法

    Vue2.0中集成UEditor富文本編輯器的方法

    本文給大家詳細講述了Vue2.0中集成UEditor富文本編輯器的方法以及相關注意事項做了講述,有興趣的朋友學習下。
    2018-03-03
  • vue中h5端打開app(判斷是安卓還是蘋果)

    vue中h5端打開app(判斷是安卓還是蘋果)

    這篇文章主要介紹了vue中h5端打開app(判斷是安卓還是蘋果),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-02-02
  • 利用vue重構有贊商城的思路以及總結整理

    利用vue重構有贊商城的思路以及總結整理

    這篇文章主要介紹了利用vue重構有贊商城的思路以及總結整理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-02-02
  • 在vue項目中使用codemirror插件實現(xiàn)代碼編輯器功能

    在vue項目中使用codemirror插件實現(xiàn)代碼編輯器功能

    這篇文章主要介紹了在vue項目中使用codemirror插件實現(xiàn)代碼編輯器功能(代碼高亮顯示及自動提示),本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-08-08
  • vue實現(xiàn)鼠標經(jīng)過顯示懸浮框效果

    vue實現(xiàn)鼠標經(jīng)過顯示懸浮框效果

    這篇文章主要為大家詳細介紹了vue實現(xiàn)鼠標經(jīng)過顯示懸浮框效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • web前端vue之vuex單獨一文件使用方式實例詳解

    web前端vue之vuex單獨一文件使用方式實例詳解

    Vuex 是一個專為 Vue.js 應用程序開發(fā)的狀態(tài)管理模式。這篇文章主要介紹了web前端vue:vuex單獨一文件使用方式,需要的朋友可以參考下
    2018-01-01
  • 詳解Vue.js v-for不支持IE9的解決方法

    詳解Vue.js v-for不支持IE9的解決方法

    這篇文章主要介紹了詳解Vue.js v-for不支持IE9的解決方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • vue頁面使用阿里oss上傳功能的實例(一)

    vue頁面使用阿里oss上傳功能的實例(一)

    本篇文章主要介紹了vue頁面使用阿里oss上傳功能的實例(一),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • VUE中Echarts的resize事件報錯和移除windows的事件問題

    VUE中Echarts的resize事件報錯和移除windows的事件問題

    這篇文章主要介紹了VUE中Echarts的resize事件報錯和移除windows的事件問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07

最新評論