vue + js 實現微信授權登錄

描述點

  • 微信相關開發知識了解
  • 微信網頁授權
  • vue router.beforeEach
  • vuex

授權詳解

  • 頁面生成地址為*********.com/site/#/?account_id=1
  • 進入頁面的時候先判斷token是否存在,如果存在直接跳轉,跳轉的時候如果接口返回401說明未登錄,執行登錄方法(就是下面的方法)
  • 根據account_id拿appid,跳轉到auth_url,拿到code和state
  • 根據code獲取到token,將token信息放到store里面,跳轉到下一頁

具體代碼詳解

  • 第一步:先將需要的信息,放在store中
//持久化當前token 相關信息
export default {
    state:{
        token:localStorage['site_current_token']?localStorage['site_current_token']:'',             //token
        account_id:localStorage['site_current_account_id']?localStorage['site_current_account_id']:0,       //當前account_id
        app_id:localStorage['site_current_app_id']?localStorage['site_current_app_id']:'',          //當前 app_id
        retry_count:0,//登錄重試次數,防止同一頁面中多個ajax同時觸發登錄操作
        after_login_go:localStorage['site_current_login_go']?localStorage['site_current_login_go']:'',//登錄后跳轉
    },
    mutations:{
        set_token(state,token){
            state.token = token;
            localStorage['site_current_token'] = token;
        },
        set_accountid(state,aid){
            state.account_id = aid;
            localStorage['site_current_account_id'] = aid;
        },
        set_appid(state,appid){
            state.app_id = appid
            localStorage['site_current_app_id'] = appid;
        },
        retry_count_add(state){
            state.retry_count ++;
        },
        set_login_go(state,path){
            state.after_login_go = path;
            localStorage['site_current_login_go'] = path;
        }
    },
    actions:{
    },
    gettters:{}
}

  • 第二步 無論使用哪個url進入網站都會先觸發router.beforeEach鉤子,所以在router.beforeEach中判斷用戶狀態
    1、如果current_token存在,跳轉到頁面,進入頁面會調取接口,如果接口返回401,未登錄,執行登錄方法(goLogin-->通過account_id獲取appid-->跳轉到auth_url--》獲取code) ,否則獲取頁面信息
    2、如果current_token不存在,并且code也不存在,執行登錄方法 (goLogin)
    3、如果current_token不存在,code存在,執行獲取token方法(通過code和appid,獲取token),然后跳轉

goLogin方法

export function goLogin(next_to){
    var account_id = store.state.token.account_id;
    var retry_count = store.state.token.retry_count;
    if (retry_count >= 1) {
        return false;
    }
    store.commit('retry_count_add');
    api.getAppId(account_id)
    .then(function(res){
        store.commit('set_appid',res.appid);
        var scope = 'snsapi_base';
        var auth_url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + res.appid + '&redirect_uri=' + encodeURIComponent(window.location.href) + '&response_type=code&scope='+scope+'&state=STATE&component_appid='+ res.component_appid + '#wechat_redirect';
        window.location.replace(auth_url);
       //點擊后,頁面將跳轉至 redirect_uri?code=CODE&state=STATE;;;;替換地址之后會重新觸發router.beforeEach
    })
    .catch(function(err){
        store.commit('set_toast_msg','AppId獲取失敗');
        console.log('獲取appid失敗',err.response);
    });
}

getToken方法

export function getToken(code,suc_func){
    var app_id = store.state.token.app_id;
    api.getToken(code,app_id).then(function(res){
        setToken(res.account_id,res);
        suc_func = suc_func?suc_func:function(){};
        suc_func();
        console.log('getToken',res);
    }).catch(function(err){
        console.log('getToken',err);
    });
}

setToken方法(將token信息放入緩存中,方便測試的時候使用token信息),清除token(clearToken)

export function setToken(account_id,token_info){
    localStorage['token_info_'+account_id] = JSON.stringify(token_info);
}

syncToken方法(從緩存中將token存入store,同時返回current_token_info.token)

export function syncToken(account_id){
    if (process.env.NODE_ENV == 'development') {
        var storage = process.env.DEV_API_TOKEN;
    }else{
        var storage = localStorage['token_info_'+account_id];
    }
    
    if (!storage) {
        return false;
    }
    //將緩存中的token信息 ,加入store
    var current_token_info = JSON.parse(storage);
    if(current_token_info){
        store.commit('set_hospital',current_token_info.hospital?current_token_info.hospital:'');
        store.commit('set_appid',current_token_info.app_id?current_token_info.app_id:'');
        store.commit('set_token',current_token_info.token?current_token_info.token:'');
        store.commit('set_accountid',current_token_info.account_id?current_token_info.account_id:0);
        return current_token_info.token?current_token_info.token:'';
    }else{
        return false;
    }
        
}

router.beforeEach

router.beforeEach((to, from, next) => {
    
    var wx_code = getQueryParam('code');
    var wx_state = getQueryParam('state');
    
    //頁面設置account_id后 重置當前訪問的account_id
    var account_id = to.query.account_id?to.query.account_id:0;
    if(account_id > 0){
        store.commit('set_accountid',account_id)    
    }else{
        account_id = store.state.token.account_id;
    }
    var current_token = syncToken(account_id);//獲取token信息
   //如果token不存在,并且code存在的時候,根據code、appid獲取token
    if(!current_token && wx_code && wx_state){
        document.title = '正在登錄...';
        getToken(wx_code,function(){
            //跳往授權跳轉前的鏈接
            if(store.state.token.after_login_go){
                next({
                    path:store.state.token.after_login_go,
                    replace:true
                });
                //清除授權跳轉臨時數據
                store.commit('set_login_go','');
            }else{
                //api 接口觸發的話 ,沒有loging_go 
                location.reload();
            }
            
        });
        return ;
    }
   //如果token存在
    if(current_token){
        next();
       //在這里進入頁面之后會調取接口,如果接口返回401,會先清除token緩存然后執行goLogin方法,如果接口返回200,則渲染數據
    }else{
        //如果token、code都不存在,頁面第一次進入的時候
        document.title = '正在登錄...';
        store.commit('set_login_go',to.fullPath);//頁面將要跳轉的地址
        goLogin();//通過account_id獲取appid,然后跳轉到auth_url,獲取code,然后會再重新執行router.beforeEach
    }
    
});

以上就是vue微信授權的方法

  • api.****(需要傳遞的參數) -----------封裝調取接口的方法
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容