ASP.NET实现企业微信接入应用实现身份认证


#需求场景

一个.net开发的web应用接入到企业微信的应用中,实现微信用户点击应用,打开web,获取到用户信息,并实现自动登录功能。

#参考

企业微信官方API文档://work.weixin.qq.com/api/doc/90000/90135/91020

#具体步骤

1、获取access_token

获取access_token是调用企业微信API接口的第一步,相当于创建了一个登录凭证,其它的业务API接口,都需要依赖于access_token来鉴权调用者身份。

  • 请求方式: GET(HTTPS)

  • 请求地址: //qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET
    注:此处标注大写的单词ID和SECRET,为需要替换的变量,根据实际获取值更新。其它接口也采用相同的标注,不再说明。

  • 参数说明:
    在这里插入图片描述

  • 权限说明:
    每个应用有独立的secret,获取到的access_token只能本应用使用,所以每个应用的access_token应该分开来获取

  • 返回结果:

{
   "errcode": 0,
   "errmsg": "ok",
   "access_token": "accesstoken000001",
   "expires_in": 7200
}

2、构造网页授权链接

如果企业需要在打开的网页里面携带用户的身份信息,第一步需要构造如下的链接来获取code参数:

//open.weixin.qq.com/connect/oauth2/authorize?appid=CORPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect

  • 参数说明:
    在这里插入图片描述

员工点击后,页面将跳转至 redirect_uri?code=CODE&state=STATE,企业可根据code参数获得员工的userid。code长度最大为512字节。

  • 示例:
    假定当前企业CorpID:wxCorpId
    访问链接://www.wanwone.com?action=get
    根据URL规范,将上述参数分别进行UrlEncode,得到拼接的OAuth2链接为:

//open.weixin.qq.com/connect/oauth2/authorize?appid=wxCorpId&redirect_uri=http%3A%2F%2Fwww.wanwone.com%2Fcgi-bin%2Fquery%3Faction%3Dget&response_type=code&scope=snsapi_base&state=#wechat_redirect

注意,构造OAuth2链接中参数的redirect_uri是经过UrlEncode的

员工点击后,页面将跳转至

//www.wanwone.com?action=get&code=AAAAAAgG333qs9EdaPbCAP1VaOrjuNkiAZHTWgaWsZQ&state=

企业可根据code参数调用获取员工的信息.

3、获取访问用户身份

该接口用于根据code获取成员信息

{
   "errcode": 0,
   "errmsg": "ok",
   "UserId":"USERID",
   "DeviceId":"DEVICEID"
}

在这里插入图片描述

b) 非企业成员授权时返回示例如下:

{
   "errcode": 0,
   "errmsg": "ok",
   "OpenId":"OPENID",
   "DeviceId":"DEVICEID"
}

在这里插入图片描述

#.Net具体代码

1、Web首页服务端代码

    protected void Page_Load(object sender, EventArgs e)
    {
        //获取配置信息(CorpId,Secret)
        Dictionary<string, string> configs = GetConfig();
        string access_token = Context.Cache["access_token"] as string;
        if (!(Context.Request["code"] != null && Context.Request["state"] != null && Context.Request["state"].ToString() == "parasaga"))
        {
            if (access_token == null)
            {
                access_token = WXQYHelper.GetAccess_token(configs["CorpId"], configs["Secret"]);
                //缓存到Cache
                Context.Cache.Insert("access_token", access_token, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(30));
            }

            if (string.IsNullOrEmpty(access_token))
            {
                //获取token失败
            }
            else
            {
                string service = Context.Request.Url.GetLeftPart(UriPartial.Path);
                //构造网页授权链接
                string redirectUrl = WXQYHelper.GetAuthLink(configs["CorpId"], service);
                //重定向到授权链接
                Context.Response.Redirect(redirectUrl);
            }
        }
        else
        {
            string code = Context.Request["code"].ToString();
            //根据code获取访问用户身份
            string uid = WXQYHelper.GetUserIdByCode(access_token, code);
            if (string.IsNullOrEmpty(uid))
            {
                //获取失败
            }
            else
            {
                //获取成功
                //进行应用本身的登录逻辑
            }
        }
    }
    public Dictionary<string, string> GetConfig()
    {
        Dictionary<string, string> configs = new Dictionary<string, string>();

        string CorpId = System.Configuration.ConfigurationManager.AppSettings["CorpId"].ToString();
        string Secret = System.Configuration.ConfigurationManager.AppSettings["Secret"].ToString();
        configs.Add("CorpId", CorpId);
        configs.Add("Secret", Secret);
        return configs;
    }

2、帮助类代码

    public class WXQYHelper
    {
        /// <summary>
        /// 获取登陆标识access_token
        /// </summary>
        /// <returns></returns>
        public static string GetAccess_token(string corpId,string secret)
        {
            string result = "";
            try
            {
                ////qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET
                string tokenUrl = "//qyapi.weixin.qq.com/cgi-bin/gettoken";
                var getStr = "corpid=" + corpId + "&corpsecret=" + secret;
                result = Common.HttpWebRequest(tokenUrl, getStr, "GET");
            }
            catch (Exception e)
            {
                //PsLog.Error("获取登陆标识失败,返回结果:" + e.ToString());
                return "";
            }
            //{
            //  "errcode": 0,
            //   "errmsg": "ok",
            //   "access_token": "accesstoken000001",
            //   "expires_in": 7200
            //}
            var jsonObj = (JObject)JsonConvert.DeserializeObject(result);

            var token = jsonObj["access_token"].ToString();
            if (!string.IsNullOrEmpty(token))
            {
                return token;
            }
            else
            {
                return "";
            }
        }
        /// <summary>
        /// 构造网页授权链接
        /// </summary>
        /// <param name="corpId"></param>
        /// <param name="appUrl"></param>
        /// <returns></returns>
        public static string GetAuthLink(string corpId,string appUrl)
        {
            string link = "";
            ////open.weixin.qq.com/connect/oauth2/authorize
            //?appid=wxCorpId
            //&redirect_uri=http%3a%2f%2fapi.3dept.com%2fcgi-bin%2fquery%3faction%3dget
            //&response_type=code
            //&scope=snsapi_base
            //&state=#wechat_redirect
            link = string.Format("{0}?appid={1}&redirect_uri={2}&response_type={3}&scope={4}&state={5}#wechat_redirect",
                "//open.weixin.qq.com/connect/oauth2/authorize",
                corpId,
                HttpUtility.UrlEncode(appUrl),
                "code",
                "snsapi_base",
                "parasaga"
                );
            return link;
        }
        /// <summary>
        /// 获取访问用户身份
        /// </summary>
        /// <param name="accessToken"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static string GetUserIdByCode(string accessToken, string code)
        {
            ////qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE

            string result = "";
            try
            {
                ////qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET
                string tokenUrl = "//qyapi.weixin.qq.com/cgi-bin/user/getuserinfo";
                var getStr = "access_token=" + accessToken + "&code=" + code;
                result = Common.HttpWebRequest(tokenUrl, getStr, "GET");
            }
            catch (Exception e)
            {
                //PsLog.Error("获取userid失败,返回结果:" + e.ToString());
                return "";
            }
			//{
			//   "errcode": 0,
			//   "errmsg": "ok",
			//   "UserId":"USERID",
			//   "DeviceId":"DEVICEID"
			//}
            var jsonObj = (JObject)JsonConvert.DeserializeObject(result);

            var uid = jsonObj["UserId"].ToString();
            if (!string.IsNullOrEmpty(uid))
            {
                return uid;
            }
            else
            {
                return "";
            }
        }
    }