1. 程式人生 > >【Vue】Vue微信授權(系列一)

【Vue】Vue微信授權(系列一)

最近算是把微信授權,sdk,接觸了一邊了,所以準備寫一個系列;

  • 微信授權
  • 微信SDK的使用,例如分享等功能
  • 小程式授權
  • 小程式微信支付
  • 小程式模板訊息

不要問我為什麼後面是小程式微信支付,小程式模板訊息,因為普通微信公眾號專案的更本不需要前端去操作太多,直接調取後臺介面就可以完成。

##Vue微信授權 這裡我們用的是Vue全家桶開發先上一張微信授權流程圖片吧: 這裡寫圖片描述

你可以嘗試著跟著這個流程圖走一遍邏輯,在開始動手和後臺商量。 我這裡大概的授權邏輯是:

  • 路由攔截:利用Vue路由攔截,判斷使用者登入狀態(後面向後臺請求的時候,讓後臺返回),如果是登入狀態就next(),否則去授權頁(這裡提示一下,我弄了一個空白頁用來授權用的author.vue) 下面
  • 獲取code:前端先獲取當前地址,傳給後臺,後臺拿到你的當前地址,通過微信提供的介面,返回一個拼接上引數(appid,redirect_uri…)的微信端授權地址,這時候前端跳轉該地址顯示微信授權頁面,使用者授權之後拿到帶有code的地址。
  • 獲取openid:擷取地址獲取code傳遞給後臺,後臺拿著code向微信伺服器請求,獲取access_token和openod並且存到資料庫,返回有用的資料。

這裡是後臺返回的微信授權頁地址: 在這裡插入圖片描述 在這裡插入圖片描述

返回帶有code的地址,正則擷取獲得code,擷取方法下面有: 在這裡插入圖片描述

下面是我router攔截、axios配置和授權頁的程式碼和註釋

router攔截

router.
beforeEach((to, from, next) => { document.title = to.meta.title //修改各個頁面的title var uid = getUid() //獲取uid if (!uid) { if (to.path === '/author') { next() } else { setToUrl(to.fullPath) next('/author') } // window.location.href = 'http://hytera.cct.work/dist/#/author'
} else { next() } })

axios配置

import axios from 'axios'
import qs from 'qs'
import { getToken, setToken } from '../lib/util'

const ajaxUrl = process.env.NODE_ENV === 'development'
  // 測試環境api介面
  ? '/'
  // 線上環境api介面
  : 'http://wenlian.cct.work'

axios.defaults.headers.common['Source'] = '1'
const newAxios = axios.create({
  baseURL: ajaxUrl,
  timeout: 5000
})

// 新增請求攔截器
newAxios.interceptors.request.use(function (config) {
  // 在傳送請求之前做些什麼
  // 獲取token
  const token = getToken()
  if (token) {
    config.headers.common['Authorization'] = `Bearer ${token}`
    // 在post請求傳送出去之前,對其進行編碼
    if (config.method === 'post') {
      config.data = qs.stringify(config.data)
    }
  }
  return config
}, function (error) {
  // 對請求錯誤做些什麼
  return error
})

// 新增響應攔截器
newAxios.interceptors.response.use(function (response) {
  // 對響應資料做點什麼
  let newToken = response.headers['new-token']
  if (newToken) {
    setToken(newToken)
  }
  return response
}, function (error) {
  // 對響應錯誤做點什麼
  return error
})

export default {
  post (url, data) {
    return newAxios({
      method: 'post',
      url: url,
      data: data
    })
  },

  get (url, params) {
    return newAxios({
      method: 'get',
      url: url,
      params
    })
  },

  delete (url, params) {
    return newAxios({
      method: 'delete',
      url: url,
      params
    })
  },

  put (url, data) {
    return newAxios({
      method: 'put',
      url: url,
      data: data
    })
  }
}

授權頁

import {getToUrl, setToken, setUid} from '../assets/lib/util'	// 封裝的快取方法
var url = getToUrl()
export default {
  created () {
    var code = this.GetUrlParame('code')			// 擷取code
    console.log(code)
    if (!code) {
      var domine = window.location.href.split('#')[0]   // 微信會自動識別#    並且清除#後面的內容
      this.$http.post('/OAutho/OAuthUrl?Ourl=' + domine)  // 如果沒有code,說明使用者還沒授權   將當前地址傳遞給後臺
        .then(res => {
          // 正則處理後臺返回的連結
          var url = /http\S*t/g.exec(res.data.url)
          url = url[0].replace(/\\u0026/g, '&')
          window.location.href = url
        })
    } else {
      this.$http.post('/OAutho/OAuthHandle?code=' + code) //如果有code,說明使用者點選了授權  將獲取到的code傳遞給後臺
        .then(res => {
          // 返回狀態和UId
          console.log(res.data)
          this.uid = res.data.UId
          setUid(this.uid)
           if (res.data.status && this.uid) {
              window.location.replace('http://wenlian.cct.work/dist/#' + url)
           }
        })
    }
  },
  data () {
    return {
      uid: ''
    }
  },
  methods: {
    // 擷取code
    GetUrlParame (parameName) {
      /// 獲取位址列指定引數的值
      /// <param name="parameName">引數名</param>
      // 獲取url中跟在問號後面的部分
      var parames = window.location.search
      // 檢測引數是否存在
      if (parames.indexOf(parameName) > -1) {
        var parameValue = ''
        parameValue = parames.substring(parames.indexOf(parameName), parames.length)
        // 檢測後面是否還有引數
        if (parameValue.indexOf('&') > -1) {
          // 去除後面多餘的引數, 得到最終 parameName=parameValue 形式的值
          parameValue = parameValue.substring(0, parameValue.indexOf('&'))
          // 去掉引數名, 得到最終純值字串
          parameValue = parameValue.replace(parameName + '=', '')
          return parameValue
        }
        return ''
      }
    }
  }
}
可能我的授權辦法有點蠢,後面有更好的辦法在修改,有不好的地方,可以優化的地方,大佬看客還希望指點出來。我改