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.****(需要传递的参数) -----------封装调取接口的方法
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,039评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,223评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,916评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,009评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,030评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,011评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,934评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,754评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,202评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,433评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,590评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,321评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,917评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,568评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,738评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,583评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,482评论 2 352

推荐阅读更多精彩内容