美文网首页
友盟分享与原生微信获取code冲突

友盟分享与原生微信获取code冲突

作者: 欢子3824 | 来源:发表于2019-02-26 11:09 被阅读0次

    前言

    由于历史遗留问题,项目中微信登录用的是原生微信的登录,即先请求 code、再 通过 code 获取 access_token,然后通过access_token调用接口,获取微信用户信息。

    之前项目中用到了友盟分享,在加入微信登录功能出现了,经常会出现了code been used, hints: [ req_id: FEMAxQaLRa-CSO ]这个问题。

    如果使用友盟获取微信用户信息也不会有这个问题,当然如果后台大佬如果愿意改代码也可以,可现实...,于是只有我们自己动手解决了。

    分析

    首先,确认问题出在哪里?

    于是,先去掉了友盟分享的相关逻辑,发现正常,基本可以确认问题出在友盟上。但是,又不能去掉项目中的友盟分享逻辑,是不是可以判断是分享时,用友盟的逻辑,如果是登录时,使用自己的逻辑?

    通过查看微信sdk的源码,我们发现,WXEntryActivity 实现了IWXAPIEventHandler,而返回的code的回调是方法onResp

    public class WXEntryActivity extends Activity implements IWXAPIEventHandler{
      @Override
        public void onResp(BaseResp resp) {
            //这里
        }
    }
    

    然后,我们去看看友盟sdk的源码

      public void a(b var1) {
            SLog.I("WXCallbackActivity 分发回调");
            if (this.a != null && var1 != null) {
                try {
                    this.a.getWXEventHandler().a(var1);
                } catch (Exception var3) {
                    SLog.error(var3);
                }
            }
    
            this.finish();
        }
    
        public void a(a var1) {
            if (this.a != null) {
                this.a.getWXEventHandler().a(var1);
            }
    
            this.finish();
        }
    

    卧槽,还混淆了,只能硬着头皮继续看了
    查看b,和微信sdk的对比,发现b即微信sdk 中的BaseResp
    b源码,已省略部分代码

    public abstract class b {
           public void a(Bundle var1) {
            var1.putInt("_wxapi_command_type", this.a());
            var1.putInt("_wxapi_baseresp_errcode", this.a);
            var1.putString("_wxapi_baseresp_errstr", this.b);
            var1.putString("_wxapi_baseresp_transaction", this.c);
            var1.putString("_wxapi_baseresp_openId", this.d);
        }
    
        public void b(Bundle var1) {
            this.a = var1.getInt("_wxapi_baseresp_errcode");
            this.b = var1.getString("_wxapi_baseresp_errstr");
            this.c = var1.getString("_wxapi_baseresp_transaction");
            this.d = var1.getString("_wxapi_baseresp_openId");
        }
    }
    

    BaseResp源码,已省略部分代码

    public abstract class BaseResp {
    
        public void toBundle(Bundle var1) {
            var1.putInt("_wxapi_command_type", this.getType());
            var1.putInt("_wxapi_baseresp_errcode", this.errCode);
            var1.putString("_wxapi_baseresp_errstr", this.errStr);
            var1.putString("_wxapi_baseresp_transaction", this.transaction);
            var1.putString("_wxapi_baseresp_openId", this.openId);
        }
    
        public void fromBundle(Bundle var1) {
            this.errCode = var1.getInt("_wxapi_baseresp_errcode");
            this.errStr = var1.getString("_wxapi_baseresp_errstr");
            this.transaction = var1.getString("_wxapi_baseresp_transaction");
            this.openId = var1.getString("_wxapi_baseresp_openId");
        }
    }
    

    由此,我们可以确认,a(b var1) 此方法为微信的回调方法。

    然后,我们再去找找,当我们发送获取code的请求时,怎么取code呢?

    if (resp.getType() == ConstantsAPI.COMMAND_SENDAUTH) {
        SendAuth.Resp authResp = (SendAuth.Resp)resp;
        String code = authResp.code;
    }
    

    判断如是SendAuth.Resp,那就是获取资料请求,然后只执行我们自己的逻辑,否则,则执行友盟原有逻辑。
    然后就是去找友盟中的SendAuth.Resp类,经过查找,发现是友盟中的com.umeng.weixin.umengwx.i

     public void b(Bundle var1) {
            super.b(var1);
            this.e = var1.getString("_wxapi_sendauth_resp_token");
            this.f = var1.getString("_wxapi_sendauth_resp_state");
            this.g = var1.getString("_wxapi_sendauth_resp_url");
            this.h = var1.getString("_wxapi_sendauth_resp_lang");
            this.i = var1.getString("_wxapi_sendauth_resp_country");
        }
    
        public void a(Bundle var1) {
            super.a(var1);
            var1.putString("_wxapi_sendauth_resp_token", this.e);
            var1.putString("_wxapi_sendauth_resp_state", this.f);
            var1.putString("_wxapi_sendauth_resp_url", this.g);
            var1.putString("_wxapi_sendauth_resp_lang", this.h);
            var1.putString("_wxapi_sendauth_resp_country", this.i);
        }
    

    SendAuth.Resp部分代码

     public void fromBundle(Bundle var1) {
                super.fromBundle(var1);
                this.code = var1.getString("_wxapi_sendauth_resp_token");
                this.state = var1.getString("_wxapi_sendauth_resp_state");
                this.url = var1.getString("_wxapi_sendauth_resp_url");
                this.lang = var1.getString("_wxapi_sendauth_resp_lang");
                this.country = var1.getString("_wxapi_sendauth_resp_country");
            }
    
            public void toBundle(Bundle var1) {
                super.toBundle(var1);
                var1.putString("_wxapi_sendauth_resp_token", this.code);
                var1.putString("_wxapi_sendauth_resp_state", this.state);
                var1.putString("_wxapi_sendauth_resp_url", this.url);
                var1.putString("_wxapi_sendauth_resp_lang", this.lang);
                var1.putString("_wxapi_sendauth_resp_country", this.country);
            }
    

    其中,i.e即为我们需要的code,剩下的就简单了,修改WXEntryActivity.a(b var)方法

    @Override
        public void a(com.umeng.weixin.umengwx.b b) {
           if (b instanceof i) {
              //处理我们自己的逻辑
            } else {
               super.a(b);
            }
    }
    

    问题完美解决。

    相关文章

      网友评论

          本文标题:友盟分享与原生微信获取code冲突

          本文链接:https://www.haomeiwen.com/subject/jywoyqtx.html