VUE開發SPA之較舒服的微信授權登入
SPA單頁應用中微信授權登入的一點思路
單頁應用應該如何解決微信授權登入的尷尬跳轉?後退無法返回?
主要遇到的問題就是
先進入單頁應用,一邊渲染頁面一邊判斷使用者有沒有登入,當判斷到沒有登入時非同步資料請求已經發送出去了,然後要跳轉到微信授權頁面,這樣就浪費了一次網路請求且使用者可能要去點選這個資料了結果…跳走了!在授權成功後用戶點選後退再次進行授權有沒有???
本文主要講述
對於單頁應用應該在哪個階段獲取微信授權?
只考慮網站完全依賴微信授權登入,一進入就要以授權的身份進入
基本思路
核心是需要有個author.vue 叫它授權中間頁好了
vue開發過程中的一些點子
由於我的業務是完全依賴微信授權登入的,也就是使用者一進來就應該是已經完成授權的
為了避免讓使用者明顯感覺到先進入網站然後又跳轉到微信授權頁面
我們從vue-router下手
基本實現思路是:
- 無論使用哪個url進入網站都會先觸發router.beforeEach鉤子
- 在router.beforeEach鉤子中判斷使用者當前登入狀態
- 若沒有登入則儲存使用者進入的url並跳轉到author授權頁面
- author授權頁面完成微信授權以及token的寫入實現使用者登入
- 獲取前面儲存的使用者進入url並跳轉
經過這樣一個流程,使用者感覺到的就是,無論從哪個url進入SPA,都會先顯示author頁面,然後再進入自己想要進入的頁面,而不是先進入自己想要進入的頁面再閃
先貼上我的實現程式碼
使用者資訊儲存在Vuex中
// holdno是我自己定義的一個工具集 裡面有各種操作方法
router.beforeEach((to, from, next) => {
if(to.path == '/author' && store.state.user.id){
// 使用者使用後退返回到授權頁,則預設回到首頁
next('/index')
return false
}
if((!holdno.cookie.get('user' ) || !store.state.user.id) && to.path != '/author'){
// 第一次進入專案
holdno.cookie.set('beforeLoginUrl', to.fullPath) // 儲存使用者進入的url
next('/author')
return false
}else if(!store.state.user.id && to.path != '/author'){
// 之前有獲取過授權
next('/author')
return false
}
next()
})
下面來看一下author頁面的處理邏輯
created () {
// 檢測會員有沒有登入
if(!holdno.cookie.get('user')){
let ua = window.navigator.userAgent.toLowerCase()
if(ua.match(/MicroMessenger/i) == 'micromessenger'){
// 跳轉到微信授權頁面
window.location.href = this.webUrl + '/Wap/User/getOpenid'
}
}else{
// 如果有token 但是vuex中沒有使用者登入資訊則做登入操作
this.login()
}
},
methods: {
login () {
let url = this.webUrl + '/Wap/User/info'
// 通過cookie中儲存的token 獲取使用者資訊
this.$http.get(url).then(response => {
response = response.body
if(response){
// 儲存使用者登入狀態(Vuex)
this.$store.commit('user', response)
setTimeout(() => {
this.goBeforeLoginUrl() // 頁面恢復(進入使用者一開始請求的頁面)
}, 2000)
}else{
this.$alert('伺服器擼貓去惹 :(', 'wrong')
if(holdno.cookie.get('user')){
// 跳轉到微信授權頁面
window.location.href = this.webUrl + '/Wap/User/getOpenid'
}
}
})
}
}
上述程式碼中 window.location.href = this.webUrl + ‘/Wap/User/getOpenid’
這一段是後端請求微信授權登入介面的地址,在後端獲取到使用者資訊及openid後再次跳轉到author頁面而不是直接定向到使用者想要請求的位置,這樣做的原因很簡單。
如果使用者跳轉到授權頁面,由後端獲取使用者資訊並儲存好登入狀態,重定向到使用者請求的頁面,這時只要使用者點選一下後退,所有的邏輯重新再來一遍有沒有?作為一個不懂技術的使用者,應該也是很鬱悶,為什麼後退還是跳回來了呢???
所以獲取使用者資訊後再次重定向到author頁面,由author做一箇中間頁檢測到獲取到使用者資訊後在前端做一個跳轉,也就是程式碼中的this.goBeforeLoginUrl()(跳轉到登入前的url …哈哈哈),這時候使用者再點選後退就會退回到author頁面而不是後端獲取使用者openid的url,但真的會再次顯示author頁面給使用者嗎?並不會,回看我們路由鉤子的定義:
router.beforeEach((to, from, next) => {
if(to.path == '/author' && store.state.user.id){
// 使用者使用後退返回到授權頁,則預設回到首頁
next('/index')
return false
}
...
})
後面部分這裡不重要,展示出來的則是關鍵部分,在再次跳轉至author前,路由鉤子被觸發,檢測到即將進入的頁面to.path == ‘/author’成立同時剛才在this.login()中做了this.$store.commit(‘user’, response)操作,所以if條件成立頁面被直接跳轉至‘/index’首頁,所以在這一個流程中,使用者並沒有再次看到授權頁面,而是直接返回到了首頁,是不是很完美!
this.goBeforeLoginUrl()
// 登入後跳轉方法
Vue.prototype.goBeforeLoginUrl = () => {
let url = holdno.cookie.get('beforeLoginUrl')
if(!url || url.indexOf('/author') != -1){
router.push('/index')
}else{
if(url == '/'){
url = '/index'
}
router.push(url)
holdno.cookie.set('beforeLoginUrl', '')
}
}
看完整個流程,author只講到邏輯處理,但它畢竟是一個頁面,也是要展示給使用者看的,只處理邏輯的話難道白花花的一片show給使用者嗎?當然不是!想必大家都瞭解app在初次啟動時都有一個廣告頁吧,我們完全可以把author授權中間頁包裝成一個廣告頁,在使用者瀏覽花哨的圖片(廣告)時默默完成授權登入的處理 :)
大概就是這麼個意思 :P
掃碼體驗
希望能有大神交流更優解決方案。