1 微信开放平台:https://open.weixin.qq.com/

2 开通流程:

微信开放平台—网站应用开发—微信登录功能 简介-风君雪科技博客

3 微信官方教程:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN

4 效果展示:

微信开放平台—网站应用开发—微信登录功能 简介-风君雪科技博客

点击微信图标跳转到https://open.weixin.qq.com/connect/…..页面

微信开放平台—网站应用开发—微信登录功能 简介-风君雪科技博客

使用个人微信扫描后,点击“确认登录”

微信开放平台—网站应用开发—微信登录功能 简介-风君雪科技博客

这时候,pc页面上就会有变化:

微信开放平台—网站应用开发—微信登录功能 简介-风君雪科技博客

然后页面就直接跳转到1好店的首页,并且将微信用户的信息传过去了。

5 通过官方提供的文档,我们可以看出一共分4个步骤

第一步:请求CODE
第二步:通过code获取access_token
第三步:通过access_token调用接口
第4步:获取用户个人信息(UnionID机制)

我们写一个api代码:  

public class weixin_helper
    {
        public weixin_helper()
        {
        }
        /// <summary>
        /// 根据AppID和AppSecret获得access token(默认过期时间为2小时)
        /// </summary>
        /// <returns>Dictionary</returns>
        public static Dictionary<string, object> get_access_token()
        {
            //获得配置信息
            oauth_config config = oauth_helper.get_config(2);
            string send_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" +
                              config.oauth_app_id + "&secret=" + config.oauth_app_key + "";
            //发送并接受返回值
            string result = Utils.HttpGet(send_url);
            if (result.Contains("errmsg"))
            {
                return null;
            }
            try
            {
                Dictionary<string, object> dic = JsonConvert.DeserializeObject<Dictionary<string, object>>(result);
                return dic;
            }
            catch
            {
                return null;
            }
        } /// <summary>
        /// 取得临时的Access Token(默认过期时间为2小时)
        /// </summary>
        /// <param name="code">临时Authorization Code</param>
        /// <param name="state">防止CSRF攻击,成功授权后回调时会原样带回</param>
        /// <returns>Dictionary</returns>
        public static Dictionary<string, object> get_access_token(string code, string state)
        {
            //获得配置信息
            oauth_config config = oauth_helper.get_config(2);
            string send_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" +
                              config.oauth_app_id + "&secret=" + config.oauth_app_key + "&code="+code+"&grant_type=authorization_code";
            //发送并接受返回值
            string result = Utils.HttpGet(send_url);
            if (result.Contains("errmsg"))
            {
                return null;
            }
            try
            {
                Dictionary<string, object> dic = JsonConvert.DeserializeObject<Dictionary<string, object>>(result);
                return dic;
            }
            catch
            {
                return null;
            }
        }
        /// <summary>
        /// 根据access_token判断access_token是否过期
        /// </summary>
        /// <param name="access_token"></param>
        /// <returns>true表示未失效</returns>
        public static bool check_access_token(string access_token)
        {
            //获得配置信息
            oauth_config config = oauth_helper.get_config(2);
            string send_url = "https://api.weixin.qq.com/sns/auth?access_token=" + access_token + "&openid=" + config.oauth_app_id;
            //发送并接受返回值
            string result = Utils.HttpGet(send_url);
            try
            {
                Dictionary<string, object> dic = JsonConvert.DeserializeObject<Dictionary<string, object>>(result);
                if (dic.ContainsKey("errmsg"))
                {
                    if (dic["errmsg"].ToString()=="ok")
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                    
                }
                return false;

            }
            catch
            {
                return false;
            }
        }


      /// <summary>
        /// 若fresh_token已过期则根据refresh_token取得新的refresh_token
      /// </summary>
        /// <param name="refresh_token">refresh_token</param>
        /// <returns>Dictionary</returns>
        public static Dictionary<string, object> get_refresh_token(string refresh_token)
        {
            //获得配置信息
            oauth_config config = oauth_helper.get_config(2);
            string send_url =
                "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=" +
                              config.oauth_app_id + "&grant_type=refresh_token&refresh_token=" + refresh_token;
            //发送并接受返回值
            string result = Utils.HttpGet(send_url);
            if (result.Contains("errmsg"))
            {
                return null;
            }
            try
            {
                Dictionary<string, object> dic = JsonConvert.DeserializeObject<Dictionary<string, object>>(result);
                return dic;
            }
            catch
            {
                return null;
            }
        }
        /// <summary>
        /// 获取登录用户自己的基本资料
        /// </summary>
        /// <param name="access_token">临时的Access Token</param>
        /// <param name="open_id">用户openid</param>
        /// <returns>Dictionary</returns>
        public static Dictionary<string, object> get_user_info(string access_token, string open_id)
        {
            //获得配置信息
            oauth_config config = oauth_helper.get_config(2);
            //发送并接受返回值   
            string send_url = "https://api.weixin.qq.com/sns/userinfo?access_token="+access_token+"&openid="+open_id;
            //发送并接受返回值
            string result = Utils.HttpGet(send_url);
            if (result.Contains("errmsg"))
            {
                return null;
            }
            //反序列化JSON
            Dictionary<string, object> dic = JsonHelper.DataRowFromJSON(result);
            return dic;
        }
    }

控制器的核心代码:

#region 微信登录

        /// <summary>
        /// 微信登录
        /// </summary>
        public ActionResult WeChat()
        {
            //获得配置信息
            oauth_config config = oauth_helper.get_config(2); //主键id
            if (config == null)
            {
                return Content("出错了,您尚未配置微信相关的API信息!");
            }
            string state = Guid.NewGuid().ToString().Replace("-", "");
            Session["oauth_state"] = state;
            string send_url =
                "https://open.weixin.qq.com/connect/qrconnect?appid=" + config.oauth_app_id +
                              "&redirect_uri=" + Utils.UrlEncode(config.return_uri.ToLower()) +
                              "&response_type=code&scope=snsapi_login&state=" + state +
                              "#wechat_redirect";
            //开始发送
            return Redirect(send_url); //跳转到微信自己 指定的关联登陆页面
        }

        /// <summary>
        /// 微信登录返回action
        /// </summary>
        public ActionResult WeChatReturnUrl(string state, string code)
        {
            //取得返回参数
            string access_token = string.Empty;
            string expires_in = string.Empty;
            string client_id = string.Empty;
            string openid = string.Empty;
            string refresh_token = string.Empty;

            if (Session["oauth_state"] == null || Session["oauth_state"].ToString() == "" ||
                state != Session["oauth_state"].ToString() || string.IsNullOrEmpty(code))//若返回参数中未包含code或者state没有通过验证则提示出错
            {
                return Content("出错啦,state未初始化!");
            }

            //第一步:通过code来获取Access Token以及openid
            Dictionary<string, object> dic1 = weixin_helper.get_access_token(code, state);
            if (dic1 == null || !dic1.ContainsKey("access_token"))
            {
                return Content("错误代码:,无法获取Access Token,请检查App Key是否正确!");
            }
            if (dic1 == null || !dic1.ContainsKey("openid"))
            {
                if (dic1.ContainsKey("errmsg"))
                {
                    return Content("errcode:" + dic1["errcode"] + ",errmsg:" + dic1["errmsg"]);
                }
                else
                {
                    return Content("出错啦,无法获取用户授权Openid!");
                }
            }

            access_token = dic1["access_token"].ToString();//获取access_token
            expires_in = dic1["expires_in"].ToString();//获取过期时间
            refresh_token = dic1["refresh_token"].ToString();//获取用于重新刷新access_token的凭证
            openid = dic1["openid"].ToString();//用户唯一标示openid

            //储存获取数据用到的信息
            Session["oauth_name"] = "webchat";
            Session["oauth_access_token"] = access_token;
            Session["oauth_openid"] = openid;
            Session["oauth_refresh_token"] = refresh_token;
            #region todo 将获取到的用户信息保存到数据库中

            #endregion
            //第二步:通过Access Token以及openid来获取用户的基本信息
            //Dictionary<string, object> dic2 = weixin_helper.get_user_info(access_token,openid);


            //第三步:跳转到指定页面
            return Content(WeChatResultJson());

        }

        /// <summary>
        /// 微信登录返回action, 处理用户信息
        /// </summary>
        public string WeChatResultJson()
        {
            string oauth_access_token = string.Empty;
            string oauth_openid = string.Empty;
            string oauth_name = string.Empty;
            string oauth_refresh_token = string.Empty;

            if (Session["oauth_name"] == null || Session["oauth_access_token"] == null ||
                Session["oauth_openid"] == null)
            {
                return "{"ret":"1", "msg":"出错啦,Access Token已过期或不存在!"}";
            }
            oauth_name = Session["oauth_name"].ToString();
            oauth_access_token = Session["oauth_access_token"].ToString();
            oauth_openid = Session["oauth_openid"].ToString();
            oauth_refresh_token = Session["oauth_refresh_token"].ToString();

            if (!weixin_helper.check_access_token(oauth_access_token)) //调用access_token前需判断是否过期
            {
                Dictionary<string, object> dic1 = weixin_helper.get_refresh_token(oauth_refresh_token);//如果已过期则重新换取新的access_token
                if (dic1 == null || !dic1.ContainsKey("access_token"))
                {
                    return "{"openid":"0", "msg":"出错啦,无法获取access_token!"}";
                }
                oauth_access_token = dic1["access_token"].ToString();
            }

            Dictionary<string, object> dic = weixin_helper.get_user_info(oauth_access_token, oauth_openid);
            if (dic == null)
            {
                return "{"openid":"0", "msg":"出错啦,无法获取授权用户信息!"}";
            }
            try
            {
                StringBuilder str = new StringBuilder();
                str.Append("{");
                str.Append(""openid": "" + dic["openid"].ToString() + "", ");
                str.Append(""nickname": "" + dic["nickname"].ToString() + "", ");
                str.Append(""sex": "" + dic["sex"].ToString() + "", ");
                str.Append(""province": "" + dic["province"].ToString() + "", ");
                str.Append(""city": "" + dic["city"].ToString() + "", ");
                str.Append(""country": "" + dic["country"].ToString() + "", ");
                str.Append(""headimgurl": "" + dic["headimgurl"].ToString() + "", ");
                str.Append(""privilege": "" + dic["privilege"].ToString() + "", ");
                str.Append(""unionid": "" + dic["unionid"].ToString() + """);
                str.Append(""oauth_name": "" + oauth_name + """);
                str.Append(""oauth_access_token": "" + oauth_access_token + """);
                str.Append(""oauth_openid": "" + oauth_openid + """);
                str.Append("}");
                return str.ToString();
            }
            catch
            {
                return "{"ret":"0", "msg":"出错啦,无法获取授权用户信息!"}";
            }

        }
        #endregion

核心代码已经写好了。

这里要感谢小亚同学辛苦写的代码。我直接拿过来使用了。

面对新的知识和技能,我们首先要仔细看官方的说明,再理清楚思路,一步一步跟着开发就行了。

小亚同学是去年刚毕业,也能把这些代码写的很好,难能可贵。