库版本.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 }
更多配置请参考视频
4、实现abp集成
找到abp.web.core/controllers/tokenauthcontroller
先注入usermanager
然后添加下面的方法
1 [httppost]
2 public async task 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
后续请求跟之前的处理就一样了。