视频教程(使用+实现原理):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
后续请求跟之前的处理就一样了。