您现在的位置是:网站首页> 编程资料编程资料

.NET Core企业微信网页授权登录的实现_实用技巧_

2023-05-24 400人已围观

简介 .NET Core企业微信网页授权登录的实现_实用技巧_

1.开发前准备

参数获取

corpid

每个企业都拥有唯一的corpid,获取此信息可在管理后台“我的企业”-“企业信息”下查看“企业ID”

secret

secret是企业应用里面用于保障数据安全的“钥匙”,每一个应用都有一个独立的访问密钥,为了保证数据的安全,secret务必不能泄漏。

框架

例子使用yishaadmin开源框架为例

2.企业微信OAuth2接入流程

第一步: 用户点击连接

第二步: Index页取得回调Code

第三步: 根据Code和access_token获取UserID

第四步: 根据UserID到通讯录接口获取其他信息

3.构造网页授权链接

假定当前企业CorpID:wxCorpId
访问链接:http://api.3dept.com/cgi-bin/query?action=get

根据URL规范,将上述参数分别进行UrlEncode,得到拼接的OAuth2链接为:

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

然后新建应用,将链接放入,配置应用可信域名。

官方文档链接:https://developer.work.weixin.qq.com/document/path/91335

4. 调用代码部分

4.1 appsettings配置

"Wx": { "corpid": "", "corpsecret": "", "baseurl": "https://qyapi.weixin.qq.com", "getUserByCode": "/cgi-bin/user/getuserinfo?access_token={0}&code={1}", "getToken": "/cgi-bin/gettoken?corpid={0}&corpsecret={1}", "getUserByUserId": "/cgi-bin/user/get?access_token={0}&userid={1}" }

4.2 配置IHttpClientFactory调用微信客户端

public static IHttpClientFactory httpClientFactory { get; set; }

Startup添加以下内容

public void ConfigureServices(IServiceCollection services) { services.AddHttpClient("WxClient", config => { config.BaseAddress = new Uri(Configuration["Wx:baseurl"]); config.DefaultRequestHeaders.Add("Accept", "application/json"); }); }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { GlobalContext.httpClientFactory = app.ApplicationServices.GetService(); }

4.3 类准备

 UserCache 类保存用户id,头像,用户名,以及code,按需新增。

using System; using System.Collections.Generic; using System.Text; namespace YiSha.Model.Result { public class UserCache { ///  /// 用户id ///  public string UserID { get; set; } ///  /// 头像 ///  public string Portrait { get; set; } ///  /// 用户名 ///  public string Username { get; set; } ///  /// 缓存最近一次Code 用于刷新时code不更新问题 ///  public string Code { get; set; } } }

ApplicationContext用于缓存Token 过期时间以及用户集合避免多次调用微信接口提高响应速度

using System;using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using YiSha.Model.Result; namespace YiSha.Admin.Web.App_Code { public static class ApplicationContext { ///  /// 用于多点登录的微信用户 ///  public const string WxUser = "taskUser"; ///  /// 用于多点登录的微信密码 ///  public const string WxPassWord = "123456"; ///  /// 过期时间 ///  public static DateTime TimeOutDate { get; set; } ///  /// Token ///  public static string Token { get; set; } ///  /// 缓存UserID Name 头像 ///  public static List UserCache { get; set; } = new List(); } }

获取Token返回实体

using System; using System.Collections.Generic; using System.Text; namespace YiSha.Entity.OAManage { public class GetTokenResult { ///  /// 错误编号 ///  public int errcode { get; set; } ///  /// 错误信息 ///  public string errmsg { get; set; } ///  /// Token ///  public string access_token { get; set; } ///  /// 过期时间 ///  public int expires_in { get; set; } } }

获取用户id返回实体

using System; using System.Collections.Generic; using System.Text; namespace YiSha.Entity.OAManage { //获取用户ID public class GetUserInfoResult { ///  /// 错误编号 ///  public int errcode { get; set; } ///  /// 错误信息 ///  public string errmsg { get; set; } ///  /// 用户ID ///  public string UserID { get; set; } } }

获取用户通讯录返回实体

using System; using System.Collections.Generic; using System.Text; namespace YiSha.Entity.OAManage { public class GetUserResult { ///  /// 错误编号 ///  public int errcode { get; set; } ///  /// 错误信息 ///  public string errmsg { get; set; } ///  /// 名称 ///  public string name { get; set; } ///  /// 头像 ///  public string avatar { get; set; } } }

4.4方法准备

获取Token方法,该方法对Token进行了一个缓存,避免重复获取.

注意事项:
开发者需要缓存access_token,用于后续接口的调用(注意:不能频繁调用gettoken接口,否则会受到频率拦截)。当access_token失效或过期时,需要重新获取。

access_token的有效期通过返回的expires_in来传达,正常情况下为7200秒(2小时),有效期内重复获取返回相同结果,过期后获取会返回新的access_token。
由于企业微信每个应用的access_token是彼此独立的,所以进行缓存时需要区分应用来进行存储。
access_token至少保留512字节的存储空间。
企业微信可能会出于运营需要,提前使access_token失效,开发者应实现access_token失效时重新获取的逻辑。

获取Token文档链接https://developer.work.weixin.qq.com/document/path/91039

///  /// 获取Token ///  /// Item1 Token;Item2 是否成功 public Tuple GetToken() { //判断Token是否存在 以及Token是否在有效期内 if(string.IsNullOrEmpty(ApplicationContext.Token) || ApplicationContext.TimeOutDate > DateTime.Now) { //构造请求链接 var requestBuild = GlobalContext.Configuration["Wx:getToken"]; requestBuild = string.Format(requestBuild, GlobalContext.Configuration["Wx:corpid"], GlobalContext.Configuration["Wx:corpsecret"] ); using (var wxClient = GlobalContext.httpClientFactory.CreateClient("WxClient")) { var httpResponse = wxClient.GetAsync(requestBuild).Result; if(httpResponse.StatusCode == System.Net.HttpStatusCode.OK) { var dynamic= JsonConvert.DeserializeObject( httpResponse.Content.ReadAsStringAsync().Result ); ApplicationContext.Token = dynamic.access_token; //过期5分钟前刷新Token var expires_in = Convert.ToDouble(dynamic.expires_in - 5 * 60); ApplicationContext.TimeOutDate = DateTime.Now.AddSeconds(expires_in); return Tuple.Create(ApplicationContext.Token,true); } else { return Tuple.Create("获取企业微信Token失败,请稍后重试!", false); } } } else { return Tuple.Create(ApplicationContext.Token, true); } }

获取用户ID方法,该方法根据获取到的token,以及回调的code进行请求,得到用户id实体

获取访问用户身份文档链接:https://developer.work.weixin.qq.com/document/path/91023

///  /// 获取用户ID ///  /// 企业微信Token /// 构造请求的回调code /// Item1 UserId;Item2 是否成功 public Tuple GetUserID(string token,string code) { //构造请求链接 var requestBuild = GlobalContext.Configuration["Wx:getUserByCode"]; requestBuild = string.Format(requestBuild,token,code); using (var wxClient = GlobalContext.httpClientFactory.CreateClient("WxClient")) { var httpResponse = wxClient.GetAsync(requestBuild).Result; if (httpResponse.StatusCode == System.Net.HttpStatusCode.OK) { var dynamic = JsonConvert.DeserializeObject( httpResponse.Content.ReadAsStringAsync().Result ); return Tuple.Create(dynamic.UserID, true); } else { return Tuple.Create("获取用户ID失败,请稍后重试!", false); } } }

获取用户通讯录方法,该方法可以通过token和userid进行获取用户头像等信息,按需要调用

读取成员接口文档:https://developer.work.weixin.qq.com/document/path/90196

///  /// 获取用户通讯录 ///  /// Item1 头像,获取失败时为错误信息;Item2 名称;Item3 是否成功 public Tuple GetUserByID(string token, string userid) { //构造请求链接 var requestBuild = GlobalContext.Configuration["Wx:getUserByUserId"]; requestBuild = string.Format(requestBuild, token, userid); //建立HttpClient us
                
                

-六神源码网