使用uView UI+UniApp開發微信小程式–判斷用戶是否登錄並跳轉

在《使用uView UI+UniApp開發微信小程式》的隨筆中,介紹了基於uView UI+UniApp開發微信小程式的一些基礎知識和準備工作,其中也大概介紹了一下基本的登錄過程,本篇隨筆詳細介紹一下微信小程式的相關登錄處理以及登錄後設置用戶身份資訊,並跳轉到相應頁面的處理過程。

1、令牌判斷和登錄方式

 在之前介紹過,在業務系統中,我們需要根據登錄用戶的身份獲取對應的數據,如果用戶沒有登錄,這些資訊是無法獲到的,那麼我們可以在app.vue中判斷用戶是否登錄,然後跳轉到對應的頁面,如下所示。

也就是系統啟動的進入的時候,我們需要對系統用戶的身份做一次判斷,判斷token是否存在,並且是否有效(因為token是有時效的)。

我們先來介紹下如何如何判斷token是否存在的處理過程,由於token本身在登陸的時候,設置了存儲,因此只需要通過uView的token獲取操作即可讀取出來,並進行判斷即可。

我們只需要簡單判斷this.vuex_token 是否存在值即可,因為this.vuex_token是由於uView在載入Mixin的時候,已經自動映射了存儲的鍵值,因此我們可以通過this.vuex_token訪問到對應的值。

如果是簡單的判斷,我們在app.vue的如下程式碼即可處理

<script>
    export default {
        globalData: {
            username: ''
        },
        onLaunch() {
            //如果用戶沒有登錄或令牌失效,跳轉到登錄介面
            // console.log(this.vuex_token)
            if(!this.vuex_token) {
                this.$u.route({
                    url: 'pages/template/login/password'
                });
            } else {
                uni.switchTab({
                    url: '/pages/example/myinfo'
                });
            }
        },
    }
</script>

不過我們需要通過判斷它的時限有效性,那麼通過判斷失效日期進行處理,如下程式碼所示。

<script>
    export default {
        onLaunch() {            
            //如果用戶沒有登錄或令牌失效,跳轉到登錄介面
            // console.log(this.vuex_token)
            console.log(this.$u.http.config.baseUrl)
            var authed = this.checkToken()            
            if(!authed) {
                this.$u.route({
                    url: '/pages/task/login/index'
                });
            } else {
                this.$u.route({
                    type:'tab',    
                    url: 'pages/task/login/myinfo'
                })
            }
        },
        methods: {
            checkToken() {                
                if(this.vuex_token && this.vuex_user) {
                    var expired = new Date(this.vuex_user.expired) //token過期時間
                    const now = Date.now()
                    if(expired - now > 0) {
                        return true
                    }
                }
                return false
            }
        }
    }
</script>

其中expired是我們獲取到token的時間,並加上token的失效時間的。

我們這裡使用了一個checkToken的函數,用來判斷是否正常登錄並且有效的,如果令牌無效,那麼跳轉到登陸介面,否則直接跳到個人資訊頁面下。

我們先來看看登錄介面,我們這裡提供了幾種登錄方式,帳號密碼登錄、簡訊驗證碼登陸、微信授權登錄幾種方式。

這幾種不同的登錄方式,都是在驗證成功後,需要獲取用戶的身份資訊,並設置到Storage存儲中去,邏輯上有相同之處。

 

2、登錄的處理邏輯

用戶登錄的時候,需要輸入用戶名,密碼,構建相關的參數後,進行登錄處理,處理過程程式碼如下所示。

submit() {
    this.$refs.uForm.validate(valid => {
        if (valid) {
            this.$u.api.User.login(this.model).then(data => {
                // 登陸成功跳轉到Tab頁面                
                uni.switchTab({
                    url: '/pages/task/login/myinfo'
                });
            });
        } else {
            console.log('驗證失敗');
        }
    });
},

其中 this.$u.api.User 是用戶API介面的統一調用方式,其中http.api.js的程式碼如下所示。

import User from '../api/user.js'
import Task from '../api/task.js'

const install = (Vue, vm) => {

    // 將各個定義的介面名稱,統一放進對象掛載到vm.$u.api(因為vm就是this,也即this.$u.api)下
    vm.$u.api = { // 將 vm 對象傳遞到模組中
        User: User(vm),
        Task: Task(vm)
    }
}

export default { install }

其中api/user.js裡面定義了訪問遠程WebAPI的操作,同時也是我們封裝一些處理邏輯的操作函數,我們可以通過ES6的Promise進行封裝一個簡單的登錄函數。

由於我們這裡登錄過程,除了用戶名密碼外,還需要appid、時間戳以及簽名參數等資訊組合,因此構建參數比較多一點。

登錄成功後,我們就調用resolve的執行即可,如果失敗,調用reject的處理。

 這樣我們就可以直接通過Promise的操作處理登錄成功後的操作了,如下程式碼所示。

this.$u.api.User.login(this.model).then(data => {
    uni.switchTab({
        url: '/pages/task/login/myinfo'
    });
});

而其中setUserToken函數,主要是便於重用的目的抽取出來,因為設置令牌和用戶資訊,是其他兩個登錄方式(簡訊登陸、微信登陸)所通用的操作。

 簡訊驗證碼的登錄方式也是類似,需要後端配合判斷簡訊的有效性即可,前端先調用後端的發送簡訊操作,如下程式碼所示

//發送簡訊驗證碼
var params = { PhoneNumber: this.tel }
this.$u.api.User.SendPhoneLoginSmsCode(params).then(res => {
    if(res.success) {
        this.$u.toast(`驗證碼已發送至手機 ${this.tel},請注意查收!`)
        this.$u.route({
            url: 'pages/task/login/code',
            params: {
                mobile:this.tel
            }
        });
    } else {
        this.$u.toast('發送出現錯誤:' + res.errorMessage)
    }
})

而前端調用的函數也就是在api/user.js中簡單封裝一下對API的調用即可。

SendPhoneLoginSmsCode(data) { // 發送登錄動態碼
    return vm.$u.post('/api/framework/User/SendPhoneLoginSmsCode', data)
},

發送的後端程式碼如下所示,主要就是放在快取中一段時間供驗證即可。

        /// <summary>
        /// 發送登錄動態碼
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        public CommonResult SendPhoneLoginSmsCode(PhoneCaptchaModel model)
        {
            //獲取隨機6位數字動態驗證碼
            var code = RandomChinese.GetRandomNumber(6);

            //使用自定義模板處理簡訊發送
            string message = string.Format(ConfigData.MySmsCodeTemplate, code);
            var smsSender = new MySmsSender();
            var result = smsSender.Send(model.PhoneNumber, message);
            if (result.Success)
            {
                var cacheKey = model.PhoneNumber;//以手機號碼作為鍵存儲驗證碼快取
                var cacheItem = new SmsLoginCodeCacheItem { Code = code, PhoneNumber = model.PhoneNumber };

                var cache = CacheManagerHelper.GetCacheItem(cacheKey, () =>
                {
                    return cacheItem;
                }, TimeSpan.FromMinutes(ConfigData.SmsCodeExpiredMinutes));
            }

            return result;
        }

驗證的時候,只需要判斷快取裡面是否存在記錄和對應驗證碼是否匹配即可,如果順利通過,那麼構建用戶的token資訊返回給前端就是。

 如果前端發送驗證碼成功,那麼登陸介面跳轉到等待輸入驗證碼的介面,如下所示。

 輸入正確的驗證碼即可順利登陸,否則過期則要求重新發送簡訊驗證碼。

submit() {
    var params = { mobile: this.mobile, smscode: this.smscode };
    console.log(params);
    this.$u.api.User.dynamiclogin(params)
        .then(res => {
            this.$u.toast('驗證成功');

            uni.switchTab({
                url: '/pages/task/login/myinfo'
            });
        })
        .catch(error => {
            console.log('驗證失敗' + error);
            this.$u.toast(error);
        });
},

如果順利登陸,則跳轉到我的頁面裡面去,展示一些常用的資訊匯總,以及常見處理操作。

 

 這裡面涉及一個退出登錄的操作,主要就是註銷當前用戶的身份,只要清空身份資訊,並跳轉到登錄首頁即可。

logout() {            
    this.$u.vuex('vuex_token', null) // 重置
    this.$u.vuex('vuex_user', null) // 重置
    this.$u.toast('退出成功,請重新登錄!')
    this.second = 0
    setTimeout(()=> {
        this.$u.route({ url: '/pages/task/login/index' })
    }, 1500)
},

鑒於篇幅原因,先介紹到這裡,關於微信授權登陸及綁定的操作過程,後續再介紹。