視頻教程(使用+實現原理):https://share.weiyun.com/57HKopT 建議直接看視頻 源碼地址:https://github.com/bxjg1987/abpGeneralModules 庫版本.net core 3.1 我的abp版本:abp5.3 .net core 3. ...
視頻教程(使用+實現原理):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
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 }View Code
更多配置請參考視頻
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 }View Code
小程式端處理
小程式調用wx.login拿到code,然後調用wx.getUserInfo拿到用戶昵稱、頭像、性別.....等數據
將上面的數據組成json Post提交到 我方伺服器/wechart-miniProgram-signin
此時會返回一個加密的cookie字元串,小程式端需要想法從響應的cookie中拿到此字元串
用上面的字元串作為cookie Post請求 我方伺服器/api/TokenAuth/WeChartMiniProgramLogin
此時服務端會返回jwtToken
後續請求跟之前的處理就一樣了。