微信定制开发系列三——微信登录

发送到手机
使用"扫一扫"即可发送至手机

这期要讲的是微信定制开发中常见的功能:微信登录,包括公众号授权登录以及微信开放平台的微信联合登录。

公众号授权登录:

要开发授权登录,首先我们需要去公众号后台接口权限里面的网页授权获取用户基本信息配置网站授权地址,这一点也是容易被遗忘的。

其次我们再开始进行开发,开发前需要了解开发文档提到的几点:

关于网页授权的两种scope的区别说明

1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)

2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。 

3、用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。 

关于网页授权access_token和普通access_token的区别

1、微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息; 

2、其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。 

关于UnionID机制

1、请注意,网页授权获取用户基本信息也遵循UnionID机制。即如果开发者有在多个公众号,或在公众号、移动应用之间统一用户帐号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,才可利用UnionID机制来满足上述需求。 

2、UnionID机制的作用说明:如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为同一用户,对同一个微信开放平台下的不同应用(移动应用、网站应用和公众帐号),unionid是相同的。 

关于特殊场景下的静默授权

1、上面已经提到,对于以snsapi_base为scope的网页授权,就静默授权的,用户无感知; 

2、对于已关注公众号的用户,如果用户从公众号的会话或者自定义菜单进入本公众号的网页授权页,即使是scope为snsapi_userinfo,也是静默授权,用户无感知。 

具体而言,网页授权流程分为四步:

1、引导用户进入授权页面同意授权,获取code 

2、通过code换取网页授权access_token(与基础支持中的access_token不同) 

3、如果需要,开发者可以刷新网页授权access_token,避免过期 

4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制) 

划重点时间:

UnionID这个参数默认都是没有的,只有当微信开放平台接入了公众号以后,此参数才会返回值过来,所以如果接到的项目是需要PC端以及微信端登录的时候,那UnionID这个参数是连接两种登录的作为用户的唯一标识,也就是说开放平台和微信公众号授权登录的OpendId是不一样的。


微信开放平台联合登录:

其实仔细看文档的小伙伴都知道,跟公众号的授权登录的开发流程一模一样,只是里面的api地址以及参数有变化,因此我这边有段通用的代码分享给大家:

    public ActionResult WechatLogin(string returnUrl) {
        string url;
        returnUrl = string.IsNullOrEmpty(returnUrl) ? "/" : returnUrl;
        string redirectUri = string.Format("{0}/host/passport/wechatoauth?returnUrl={1}", 
        ConfigurationManager.AppSettings["WebDomain"].TrimEnd('/'), returnUrl);
        if (Request.ServerVariables["HTTP_USER_AGENT"].IndexOf("Mobile",
         StringComparison.Ordinal) > -1) {
            url =
                string.Format(
                    "https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}
                    &response_type=code&scope=snsapi_userinfo&state=isMobile#wechat_redirect", 
                    WxPayConfig.APPID, redirectUri);
        }
        else {
            url = string.Format(
                "https://open.weixin.qq.com/connect/qrconnect?appid={0}&redirect_uri={1}
                &response_type=code
                &scope=snsapi_login&state=isPc#wechat_redirect", WxPayConfig.OPENAPPID, redirectUri);
        }
        return Redirect(url);
    }

    public ActionResult WechatOauth(string code, string state, string returnUrl = "") {
        returnUrl = string.IsNullOrEmpty(returnUrl) ? "/" : returnUrl;
        string appId, appSecret;
        if (state == "isPc") {
            appId = WxPayConfig.OPENAPPID;
            appSecret = WxPayConfig.OPENAPPSECRET;
        }
        else {
            appId = WxPayConfig.APPID;
            appSecret = WxPayConfig.APPSECRET;
        }
        var token = WeChatUtil.GetOAuthToken(code, appId, appSecret);
        var userModel = WeChatUtil.GetUserInfo(token.access_token, token.openid);
        Log.Info("userModel", JsonConvert.SerializeObject(userModel));
        string openId = !string.IsNullOrWhiteSpace(userModel.unionid) ? userModel.unionid : userModel.openid;
        var bind =
                _accountBindingService.GetAccountBinding(new AccountBindingQuery {
                    Identification = openId,
                    AccountTypeKey = "WechatOauth"
                });
        CustomerDomain user;
        if (bind != null) {
            user = _customerService.GetCustomer(bind.UserId);
            bind.AccessToken = token.access_token;
            bind.Update();
        }
        else {
            user = new CustomerDomain() {
                Account = new AccountDomain { Account = userModel.openid, Password = userModel.openid },
                Avatar = string.Format("[{{\"filePath\":\"{0}\",\"title\":\"\",\"description\":\"\"}}]",
                 userModel.headimgurl),
                Nickname = userModel.nickname,
                Gender = userModel.sex == "1" ? CustomerEnums.GenderType.Male : CustomerEnums.GenderType.Female,
                IsValid = CustomerEnums.UserStatus.Valid
            };
            _customerService.Register(user, new FormCollection());
            UserContext.SignIn(user.Account, false);
            bind = new AccountBindingDomain { UserId = user.Id, AccessToken = token.access_token,
             NickName = user.Nickname, AccountTypeKey = "WechatOauth", Identification = openId };
            bind.Create();
        }
        UserContext.SignIn(user.Account, false);
        AfterWechatLoginEventRegister.AfterWechatLogin(user, userModel);
        return Redirect(returnUrl);
    }
}

好了,这期就到这里了,我要讲的都在代码里面了,请小伙伴们仔细品味吧!

阅读相关主题
微信定制开发系列三——微信登录

微信定制开发系列三——微信登录

分享:

标签: