1. 程式人生 > >ASP.NET實現企業微信接入應用實現身份認證

ASP.NET實現企業微信接入應用實現身份認證

[toc] --- ### #需求場景 一個.net開發的web應用接入到企業微信的應用中,實現微信使用者點選應用,開啟web,獲取到使用者資訊,並實現自動登入功能。 ### #參考 企業微信官方API文件:[https://work.weixin.qq.com/api/doc/90000/90135/91020](https://work.weixin.qq.com/api/doc/90000/90135/91020) ### #具體步驟 #### 1、獲取access_token 獲取access_token是呼叫企業微信API介面的第一步,相當於建立了一個登入憑證,其它的業務API介面,都需要依賴於access_token來鑑權呼叫者身份。 - 請求方式: GET(HTTPS) - 請求地址: https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET 注:此處標註大寫的單詞ID和SECRET,為需要替換的變數,根據實際獲取值更新。其它介面也採用相同的標註,不再說明。 - 引數說明: ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200925113845792.png#pic_center) - 許可權說明: 每個應用有獨立的secret,獲取到的access_token只能本應用使用,所以每個應用的access_token應該分開來獲取 - 返回結果: ```xml { "errcode": 0, "errmsg": "ok", "access_token": "accesstoken000001", "expires_in": 7200 } ``` #### 2、構造網頁授權連結 如果企業需要在開啟的網頁裡面攜帶使用者的身份資訊,第一步需要構造如下的連結來獲取code引數: > https://open.weixin.qq.com/connect/oauth2/authorize?appid=CORPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect - 引數說明: ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2020092513550594.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dpbGxpbmd0b2xvdmU=,size_16,color_FFFFFF,t_70#pic_center) 員工點選後,頁面將跳轉至 redirect_uri?code=CODE&state=STATE,企業可根據code引數獲得員工的userid。code長度最大為512位元組。 - 示例: 假定當前企業CorpID:wxCorpId 訪問連結:http://www.wanwone.com?action=get 根據URL規範,將上述引數分別進行UrlEncode,得到拼接的OAuth2連結為: > https://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的 員工點選後,頁面將跳轉至 > http://www.wanwone.com?action=get&code=AAAAAAgG333qs9EdaPbCAP1VaOrjuNkiAZHTWgaWsZQ&state= 企業可根據code引數呼叫獲取員工的資訊. #### 3、獲取訪問使用者身份 該介面用於根據code獲取成員資訊 - 請求方式:GET(HTTPS) - 請求地址:https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE - 引數說明: - 引數 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200925140016598.png#pic_center) - 許可權說明: 跳轉的域名須完全匹配access_token對應應用的可信域名,否則會返回50001錯誤。 - 返回結果: a) 當用戶為企業成員時返回示例如下: ```xml { "errcode": 0, "errmsg": "ok", "UserId":"USERID", "DeviceId":"DEVICEID" } ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200925140252617.png#pic_center) b) 非企業成員授權時返回示例如下: ```xml { "errcode": 0, "errmsg": "ok", "OpenId":"OPENID", "DeviceId":"DEVICEID" } ``` ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2020092514033983.png#pic_center) ### #.Net具體程式碼 #### 1、Web首頁服務端程式碼 ```csharp protected void Page_Load(object sender, EventArgs e) { //獲取配置資訊(CorpId,Secret) Dictionary 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 GetConfig() { Dictionary configs = new Dictionary(); 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、幫助類程式碼 ```csharp public class WXQYHelper { /// /// 獲取登陸標識access_token ///
/// public static string GetAccess_token(string corpId,string secret) { string result = ""; try { //https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET string tokenUrl = "https://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 ""; } } /// /// 構造網頁授權連結 ///
/// /// /// public static string GetAuthLink(string corpId,string appUrl) { string link = ""; //https://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", "https://open.weixin.qq.com/connect/oauth2/authorize", corpId, HttpUtility.UrlEncode(appUrl), "code", "snsapi_base", "parasaga" ); return link; } /// /// 獲取訪問使用者身份 ///
/// /// /// public static string GetUserIdByCode(string accessToken, string code) { //https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE string result = ""; try { //https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET string tokenUrl = "https://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 ""; } } } `