微信公众号登录功能介绍

       最近做的微信公众号,需要添加一项实名认证功能。如果未认证,公众号部分功能不对外开放。这就需要用户的公众号与认证信息一一对应,所以我们需要用户的授权获取用户的公众号信息

       根据微信官方文档-公众号的网页授权内容,与我在项目中实际运用情况总结如下:

       第一步:用户同意授权,获取code

       通过访问微信公众号接口地址:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redire

appid公众号的唯一标识
redirect_uri访问接口获得code后回跳到自己项目的页面地址
response_type固定值code
scope

应用授权作用域:

snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid)。

snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 )

state

重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节。

注:此参数是公众号为开发者预留的一个参数,供开发者自行使用。

#wechat_redirect此参数为特定值,微信公众号官方需要的参数

 

如果接口参数scope的值为:snsapi_userinfo,会弹出授权页面,同意授权后,将跳转至:redirect_uri/?code=CODE&state=STATE。

如果接口参数scope的值为:snsapi_base ,页面将跳转至 redirect_uri/?code=CODE&state=STATE。CODE值是接口返回值,STATE是用户在接口自定义的值。在我的项目里redirect_uri的地址指向的首页,然后通过页面加载函数访问了WCF接口,将code和state传入WCF接口,通过下面的步骤判断是否实名认证。

       第二步:通过code换取网页授权access_token和openid

       此openid不是最终需要的openid,用户访问公众号页面,会产生一个用户和公众号唯一的openid。

       通过访问微信公众号接口地址:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

appid公众号的唯一标识
appsecret公众号的appsecret
code填写第一步获取的code参数
grant_type固定值authorization_code

 

       第三步:拉取用户信息(需scope为snsapi_userinfo)

       通过访问微信公众号接口地址: https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

access_token网页授权接口调用凭证,上一步获取的access_token
openid用户的唯一标识:上一步获取的openid
langzh_CN 简体,zh_TW 繁体,en 英

 

获取到用户基本信息,包括openid、昵称。性别。省份。城市、国家、头像等。

       下面粘贴项目中用到的代码:

export default {
  name: "empety",
  mounted() {
    this.GetCode();
  },
  methods: {
    GetCode(){
      var appid="wxc673835c46bca3dd";
      var redirect_uri=encodeURIComponent("https://123.com.cn/#/index");
      var https="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+appid;
      https+="&redirect_uri="+redirect_uri+"&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect"
      window.location.href=https;
    }
  }
};

我的项目前端使用VUE搭建的。GetCode是页面加载调用的方法,通过调用微信公众号接口获得code,然后重定向的页面:https://123.com.cn/#/index?code=CODE&state=1

GetAuthorizeCode() {
  var code = this.GetQueryString1("code");
  var state = this.GetQueryString1("state").split("#")[0];

  GetAuthorizeCode(
    "call_GetAuthorizeCode/" + code + "/" + state,
    "call_GetAuthorizeCode"
  )
    .then((response) => {
      var data = response.data;
      if (data.tb != null) {
        var row = data.tb[0];
        console.log(data);
        this.$store.state.system.certificate = true;
        this.$store.state.system.openid = row["openid"];
        this.$store.state.system.cardno = row["cardno"];
        this.$store.state.system.patientid = row["patientid"];
        this.$store.state.system.patientname = row["patientname"];
        this.$store.state.system.hospitalid = row["hospitalid"];
        this.$store.state.system.hospitalname = row["hospitalname"];
        this.$store.state.system.serveraddress = row["serveraddress"];
        this.$store.state.system.servertype = row["hospitalid"];
      } else {
         if (isNaN(data.code) && typeof data.code !== "number") {
          this.$store.state.system.openid = data.code;
          this.$message.warning("欢迎你,请实名认证");
        }
        console.log(data.code);
      }
    })
    .catch(function (error) {
      console.log(error);
    });
},
GetQueryString1(name) {
  var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
  var r = window.location.href.split("?")[1].match(reg);
  if (r != null) return unescape(r[2]);
  return null;
},

进入index页面,执行方法GetAuthorizeCode()调用后台WCF接口GetAuthorizeCode。

        /// <summary>
        /// 获得认证信息
        /// </summary>
        /// <param name="callBackName"></param>
        /// <returns></returns>
        public Stream GetAuthorizeCode(string callBackName, string code, string state)
        {

            string appid = System.Configuration.ConfigurationManager.AppSettings.Get("appid");
            string secret = System.Configuration.ConfigurationManager.AppSettings.Get("secret");
            int result;

            string tokens = GetAccessToken(appid, secret, code);
            if (int.TryParse(tokens, out result)) return ObjectToJson(GetResultCer(result, null), callBackName);

            string access_token = tokens.Split(';')[0];
            string openid = tokens.Split(';')[1];
            string _openid = GetUserInfo(access_token, openid);
            if (int.TryParse(_openid, out result)) return ObjectToJson(GetResultCer(result, null), callBackName);

            //string auth = Auth(access_token, _openid);

            var tb = HemodialysisDB.DAL.CERTIFICATION.GetModelByOpenId(_openid);
            if (tb != null && tb.Rows.Count > 0)
            return ObjectToJson(GetResultCer(_openid, null), callBackName);
        }
        /// <summary>
        /// 获得token信息
        /// </summary>
        /// <param name="appid"></param>
        /// <param name="secret"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private string GetAccessToken(string appid, string secret, string code)
        {
            string url = string.Format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", appid, secret, code);
            string gettstr = getstr(url);
            JObject obj = (JObject)JsonConvert.DeserializeObject(gettstr);
            JToken err;
            if (!obj.TryGetValue("errcode", out err))
            {
                string access_token = obj.Value<string>("access_token");
                string openid = obj.Value<string>("openid");
                return access_token + ";" + openid;
            }
            else
            {
                return obj.Value<string>("errcode");
            }
        }
        /// <summary>
        /// 获得用户信息
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="openid"></param>
        /// <returns></returns>
        private string GetUserInfo(string access_token, string openid)
        {
            string url = string.Format("https://api.weixin.qq.com/sns/userinfo?access_token={0}&openid={1}&lang=zh_CN", access_token, openid);
            string gettstr = getstr(url);
            JObject obj = (JObject)JsonConvert.DeserializeObject(gettstr);
            JToken err;
            if (!obj.TryGetValue("errcode", out err))
            {
                string _openid = obj.Value<string>("openid");
                return _openid;
            }
            else
            {
                return obj.Value<string>("errcode");
            }
        }
        /// <summary>
        /// 验证openid
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="openid"></param>
        /// <returns></returns>
        private string Auth(string access_token, string openid)
        {
            string url = string.Format("https://api.weixin.qq.com/sns/auth?access_token={0}&openid={1}", access_token, openid);
            string gettstr = getstr(url);
            JObject obj = (JObject)JsonConvert.DeserializeObject(gettstr);
            string errcode = obj.Value<string>("errcode");
            return errcode;
        }
        private string getstr(string url)
        {
            var request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "GET";
            request.ContentType = "application/json;charset=UTF-8";
            var response = (HttpWebResponse)request.GetResponse();
            var responseString = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")).ReadToEnd();

            return responseString;
        }
        private string poststr(string url, string jsonData)
        {
            var request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.ContentType = "application/json;charset=UTF-8";
            byte[] byteData = Encoding.UTF8.GetBytes(jsonData);
            int length = byteData.Length;
            request.ContentLength = length;
            Stream writer = request.GetRequestStream();
            writer.Write(byteData, 0, length);
            writer.Close();
            var response = (HttpWebResponse)request.GetResponse();
            var responseString = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")).ReadToEnd();

            return responseString;
        }
        private ResultCer GetResultCer(Object code, DataTable tb)
        {
            return new ResultCer { code = code.ToString(), tb = tb };
        }
        private Stream ObjectToJson(object detailList, string callbackName)
        {
            string str = JsonConvert.SerializeObject(detailList);
            str = "" + callbackName + "(" + str + ")";
            return new MemoryStream(Encoding.UTF8.GetBytes(str));
        }
        private string GetObj(Stream content, string key)
        {
            StreamReader sr = new StreamReader(content);
            string str = sr.ReadToEnd();
            sr.Dispose();

            NameValueCollection collections = HttpUtility.ParseQueryString(str);
            string value = collections[key];
            string data = HttpUtility.UrlDecode(value, System.Text.Encoding.UTF8);
            return data;
        }

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旭日升的博客园

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值