描述点
- 微信相关开发知识了解
- 微信网页授权
- 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.****(需要传递的参数) -----------封装调取接口的方法