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.****(需要传递的参数) -----------封装调取接口的方法

你可能感兴趣的:(vue + js 实现微信授权登录)