描述點
- 微信相關開發知識了解
- 微信網頁授權
- 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.****(需要傳遞的參數) -----------封裝調取接口的方法