天天看点

asp.net core 3.x 微信小程序登录库(也可用于abp)

视频教程(使用+实现原理):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

asp.net core 3.x 微信小程序登录库(也可用于abp)

3、修改启动配置类abp.web.host//StartupAuthConfigurer.cs

因为startup中是通过这个类中的静态方法注册身份验证相关服务的

asp.net core 3.x 微信小程序登录库(也可用于abp)
asp.net core 3.x 微信小程序登录库(也可用于abp)
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

asp.net core 3.x 微信小程序登录库(也可用于abp)

然后添加下面的方法

asp.net core 3.x 微信小程序登录库(也可用于abp)
asp.net core 3.x 微信小程序登录库(也可用于abp)
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

后续请求跟之前的处理就一样了。