视频教程(使用+实现原理):https://share.weiyun.com/57HKopT 建议直接看视频
源码地址:https://github.com/bxjg1987/abpGeneralModules
库版本.net core 3.1
我的abp版本:abp5.3 .net core 3.1
请先看微信小程序官方文档。下面说说abp中如何使用。原生asp.net core可以参考实现
服务端配置
1、安装nuget包
Install-Package BXJG.WeChart -Version 1.0.0
2、修改配置文件 abp.web.host/appsettings.json
扫描二维码关注公众号,回复:
10085276 查看本文章
3、修改启动配置类abp.web.host//StartupAuthConfigurer.cs
因为startup中是通过这个类中的静态方法注册身份验证相关服务的
1 public static void Configure(IServiceCollection services, IConfiguration configuration) 2 { 3 var authBuilder = services.AddAuthentication(options => 4 { 5 options.DefaultAuthenticateScheme = "JwtBearer"; 6 options.DefaultChallengeScheme = "JwtBearer"; 7 }); 8 9 if (bool.Parse(configuration["Authentication:JwtBearer:IsEnabled"])) 10 { 11 authBuilder.AddJwtBearer("JwtBearer", options => 12 { 13 options.Audience = configuration["Authentication:JwtBearer:Audience"]; 14 15 options.TokenValidationParameters = new TokenValidationParameters 16 { 17 // The signing key must match! 18 ValidateIssuerSigningKey = true, 19 IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(configuration["Authentication:JwtBearer:SecurityKey"])), 20 21 // Validate the JWT Issuer (iss) claim 22 ValidateIssuer = true, 23 ValidIssuer = configuration["Authentication:JwtBearer:Issuer"], 24 25 // Validate the JWT Audience (aud) claim 26 ValidateAudience = true, 27 ValidAudience = configuration["Authentication:JwtBearer:Audience"], 28 29 // Validate the token expiry 30 ValidateLifetime = true, 31 32 // If you want to allow a certain amount of clock drift, set that here 33 ClockSkew = TimeSpan.Zero 34 }; 35 36 options.Events = new JwtBearerEvents 37 { 38 OnMessageReceived = QueryStringTokenResolver 39 }; 40 }); 41 } 42 43 if (bool.Parse(configuration["Authentication:WeChartMiniProgram:IsEnabled"])) 44 { 45 authBuilder.AddWeChartMiniProgram(opt => 46 { 47 opt.AppId = configuration["Authentication:WeChartMiniProgram:AppId"]; 48 opt.Secret = configuration["Authentication:WeChartMiniProgram:Secret"]; 49 50 opt.ClaimActions.MapJsonKey("nickName", "nickName"); 51 opt.ClaimActions.MapJsonKey("avatarUrl", "avatarUrl"); 52 opt.ClaimActions.MapJsonKey("gender", "gender"); 53 opt.ClaimActions.MapJsonKey("country", "country"); 54 opt.ClaimActions.MapJsonKey("province", "province"); 55 opt.ClaimActions.MapJsonKey("city", "city"); 56 opt.ClaimActions.MapJsonKey("language", "language"); 57 }); 58 } 59 }
更多配置请参考视频
4、实现abp集成
找到abp.web.core/controllers/TokenAuthController
先注入UserManager
然后添加下面的方法
1 [HttpPost] 2 public async Task<ExternalAuthenticateResultModel> WeChartMiniProgramLoginAsync() 3 { 4 5 //从第三方登录拿到当前用户(包含openId、sessionKey) 6 var t = await base.HttpContext.AuthenticateAsync(MiniProgramConsts.AuthenticationScheme);//间接使用第三方身份验证方案获取信息 7 //拿到openId 8 var openid = t.Principal.Claims.Single(c => c.Type == ClaimTypes.NameIdentifier).Value; 9 var tenancyName = GetTenancyNameOrNull(); 10 //尝试做第三发登录(内部通过openid找到本地账号做登录), 11 var loginResult = await _logInManager.LoginAsync(new UserLoginInfo(MiniProgramConsts.AuthenticationScheme, openid, MiniProgramConsts.AuthenticationSchemeDisplayName), tenancyName); 12 //根据登录结果,若成功则直接返回jwtToken 或者自动注册后返回 13 switch (loginResult.Result) 14 { 15 case AbpLoginResultType.Success: 16 { 17 //更新微信用户信息 18 foreach (var item in t.Principal.Claims) 19 { 20 await userManager.ReplaceClaimAsync(loginResult.User, new Claim(item.Type, ""), item); 21 } 22 23 //返回jwtToken 24 var accessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity)); 25 return new ExternalAuthenticateResultModel 26 { 27 AccessToken = accessToken, 28 EncryptedAccessToken = GetEncryptedAccessToken(accessToken), 29 ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds 30 }; 31 } 32 case AbpLoginResultType.UnknownExternalLogin: 33 { 34 //若未找到关联的本地账号则自动注册,再返回jwtToken 35 var newUser = await RegisterExternalUserAsync(new ExternalAuthUserInfo 36 { 37 Provider = MiniProgramConsts.AuthenticationScheme, 38 ProviderKey = openid, 39 Name = t.Principal.Claims.SingleOrDefault(c => c.Type == "nickName")?.Value, 40 EmailAddress = Guid.NewGuid().ToString("N") + "@mp.com", 41 Surname = "a" 42 }); 43 if (!newUser.IsActive) 44 { 45 return new ExternalAuthenticateResultModel 46 { 47 WaitingForActivation = true 48 }; 49 } 50 51 // Try to login again with newly registered user! 52 loginResult = await _logInManager.LoginAsync(new UserLoginInfo(MiniProgramConsts.AuthenticationScheme, openid, MiniProgramConsts.AuthenticationSchemeDisplayName), tenancyName); 53 if (loginResult.Result != AbpLoginResultType.Success) 54 { 55 throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt( 56 loginResult.Result, 57 openid, 58 tenancyName 59 ); 60 } 61 //保存微信用户信息(排出openid,因为它存储在userlogins里) 62 await userManager.AddClaimsAsync(loginResult.User, t.Principal.Claims.Where(c=>c.Type!= ClaimTypes.NameIdentifier)); 63 64 return new ExternalAuthenticateResultModel 65 { 66 AccessToken = CreateAccessToken(CreateJwtClaims(loginResult.Identity)), 67 ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds 68 }; 69 } 70 default: 71 { 72 throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt( 73 loginResult.Result, 74 openid, 75 tenancyName 76 ); 77 } 78 } 79 }
小程序端处理
小程序调用wx.login拿到code,然后调用wx.getUserInfo拿到用户昵称、头像、性别.....等数据
将上面的数据组成json Post提交到 我方服务器/wechart-miniProgram-signin
此时会返回一个加密的cookie字符串,小程序端需要想法从响应的cookie中拿到此字符串
用上面的字符串作为cookie Post请求 我方服务器/api/TokenAuth/WeChartMiniProgramLogin
此时服务端会返回jwtToken
后续请求跟之前的处理就一样了。