上回分解到AbpZero的auth登录机制,这里我们开始着手逐步实现我们的auth登录。
我们新建一个类库XXXX.Web.Authentication.External
在类库下新建一个类QYWechatAuthProviderApi.cs并继承ExternalAuthProviderApiBase 由于我用的是盛派的SDK,所以还要在项目Nuget盛派的工程dll
1 using Abp.AspNetZeroCore.Web.Authentication.External; 2 using Abp.Domain.Repositories; 3 using Abp.Runtime.Caching; 4 using Newtonsoft.Json; 5 using Newtonsoft.Json.Linq; 6 using Newtonsoft.Json.Schema; 7 using Senparc.Weixin; 8 using Senparc.Weixin.HttpUtility; 9 using Senparc.Weixin.Work.AdvancedAPIs.OAuth2; 10 using System; 11 using System.Collections.Generic; 12 using System.Globalization; 13 using System.IO; 14 using System.Linq; 15 using System.Net; 16 using System.Net.Http; 17 using System.Net.Http.Headers; 18 using System.Security.Cryptography; 19 using System.Text; 20 using System.Threading.Tasks; 21 22 namespace XXXX.Web.Authentication.External 23 { 24 public class WechatAuthProviderApi : ExternalAuthProviderApiBase 25 { 26 public const string Name = "Wechat"; 27 private readonly ICacheManager _cacheManager; 28 private readonly IExternalAuthConfiguration _externalAuthConfiguration; 29 WeChatMiniProgramOptions _options; 30 JSchema schema = JSchema.Parse(JsonConvert.SerializeObject(new UsersWechat())); 31 public WechatAuthProviderApi(ICacheManager cacheManager,IExternalAuthConfiguration externalAuthConfiguration) 32 { 33 _cacheManager = cacheManager; 34 _externalAuthConfiguration = externalAuthConfiguration; 35 var r = externalAuthConfiguration.Providers.First(p => p.Name == Name); 36 _options = new WeChatMiniProgramOptions 37 { 38 AppId = r.ClientId, 39 Secret = r.ClientSecret 40 }; 41 42 } 43 public override async Task<ExternalAuthUserInfo> GetUserInfo(string accessCode) 44 { 45 UsersWechat wechat = new UsersWechat(); 46 47 48 string accessToken = _cacheManager.GetCache("CacheName").Get("Login", () => GetToken(_options.AppId, _options.Secret)); 49 if (!string.IsNullOrWhiteSpace(accessToken)) 50 { 51 var url = string.Format(Config.ApiWorkHost + "/cgi-bin/user/getuserinfo?access_token={0}&code={1}", accessToken, accessCode); 52 53 var redata = Get.GetJson<GetUserResult>(url); 54 if (!string.IsNullOrWhiteSpace(redata.user_ticket)) 55 { 56 UserTicket tiket = new UserTicket 57 { 58 user_ticket = redata.user_ticket 59 }; 60 url = string.Format(Config.ApiWorkHost + "/cgi-bin/user/getuserdetail?access_token={0}", accessToken); 61 // wechat = Post.GetResult<UsersWechat>(JsonConvert.SerializeObject(tiket)); 62 wechat = await GetUserMsg(url, tiket); 63 } 64 } 65 66 var t = wechat == null ? new ExternalAuthUserInfo() : new ExternalAuthUserInfo 67 { 68 EmailAddress = wechat.email, 69 Surname = wechat.name, 70 ProviderKey = wechat.userid, 71 Provider = Name, 72 Name = wechat.userid 73 }; 74 return t; 75 76 } 77 78 79 80 private async Task<UsersWechat> GetUserMsg(string url, UserTicket tiket) 81 { 82 //序列化将要传输的对象 83 string obj = JsonConvert.SerializeObject(tiket); 84 HttpContent content = new StringContent(obj); 85 86 HttpClient client = new HttpClient(); 87 client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 88 89 var result = await client.PostAsync(url, content); 90 if (result.IsSuccessStatusCode) 91 { 92 string re = await result.Content.ReadAsStringAsync(); 93 var jo = JObject.Parse(re); 94 if (jo.IsValid(schema)) 95 { 96 var m = JsonConvert.DeserializeObject<UsersWechat>(re); 97 return m; 98 } 99 } 100 return null; 101 } 102 103 104 private string GetToken(string AppId, string Secret) 105 { 106 if (string.IsNullOrWhiteSpace(AppId) || string.IsNullOrWhiteSpace(Secret)) 107 { 108 return ""; 109 } 110 return Senparc.Weixin.Work.Containers.AccessTokenContainer.TryGetTokenAsync(AppId, Secret).Result; 111 } 112 113 public class UsersWechat 114 { 115 public string userid { get; set; } 116 public string name { get; set; } 117 118 public string mobile { get; set; } 119 120 public string gender { get; set; } 121 122 public string email { get; set; } 123 124 public string avatar { get; set; } 125 126 public string qr_code { get; set; } 127 128 } 129 130 public class GetUserResult 131 { 132 public string errcode { get; set; } 133 public string errmsg { get; set; } 134 public string CorpId { get; set; } 135 public string UserId { get; set; } 136 public string DeviceId { get; set; } 137 138 public string user_ticket { get; set; } 139 140 public string expires_in { get; set; } 141 142 } 143 144 public class UserTicket 145 { 146 public string user_ticket { get; set; } 147 } 148 149 } 150 }
以上就是企业微信登录的代码了。
最后,我们怎么开启企业微信的登录呢?
我们还需要再运行站点下的appsettings.json文件中加上我们企业微信的appid和密钥
1 "Facebook": { 2 "IsEnabled": "true", 3 "AppId": "", 4 "AppSecret": "" 5 }, 6 "Google": { 7 "IsEnabled": "true", 8 "ClientId": "", 9 "ClientSecret": "" 10 }, 11 "Wechat": { 12 "IsEnabled": "true", 13 "AppId": "xxxx", 14 "Secret": "xxx" 15 16 },
最后一步:在站点的BanchWebHostModule.cs的ConfigureExternalAuthProviders方法下添加注册
1 if (bool.Parse(_appConfiguration["Authentication:Wechat:IsEnabled"])) 2 { 3 externalAuthConfiguration.Providers.Add( 4 new ExternalLoginProviderInfo( 5 WechatAuthProviderApi.Name, 6 _appConfiguration["Authentication:Wechat:AppId"], 7 _appConfiguration["Authentication:Wechat:Secret"], 8 typeof(QYWechatAuthProviderApi) 9 ) 10 ); 11 }
自此,企业微信登录就完成了,这里主要用到的是依赖注入和反射。