ABP Vnext 扩展微信小程序授权登录
微信返回数据字段类- Code2Session 类
public class Code2Session { /// <summary> /// 用户唯一标识 /// </summary> public string openid { get; set; } /// <summary> /// 会话密钥 /// </summary> public string session_key { get; set; } /// <summary> /// 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台帐号下会返回 /// </summary> public string unionid { get; set; } /// <summary> /// 错误码 /// </summary> public int errcode { get; set; } /// <summary> /// 错误信息 /// </summary> public string errmsg { get; set; } }
在HttpApi.Host新建类
using IdentityServer4.Validation; using Microsoft.AspNetCore.Identity; using System; using System.Collections.Generic; using System.Security.Claims; using System.Threading.Tasks; using Volo.Abp.Identity; using Volo.Abp.Json; using System.Net.Http; namespace Demo { public class ExtensionGrantTypes { //扩展授权名称 public const string WeChatGrantType = "wechat_code"; } public class WeChatGrantValidator : IExtensionGrantValidator { public string GrantType => ExtensionGrantTypes.WeChatGrantType; private readonly UserManager<Volo.Abp.Identity.IdentityUser> _userManager; private readonly IJsonSerializer _jsonSerializer; public WeChatGrantValidator( UserManager<Volo.Abp.Identity.IdentityUser> userLoginManager, IJsonSerializer jsonSerializer) { _userManager = userLoginManager; _jsonSerializer = jsonSerializer; } public async Task ValidateAsync(ExtensionGrantValidationContext context) { string code = context.Request.Raw.Get("Code"); if (string.IsNullOrEmpty(code)) { context.Result = new GrantValidationResult(IdentityServer4.Models.TokenRequestErrors.InvalidGrant); } //微信开发平台验证 string _appid = "自己的appid"; string _secret = "自己的secret"; string url = string.Format( "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code", _appid, _secret, code); HttpClient client = new HttpClient(); HttpResponseMessage response = client.GetAsync(url).Result; if (response.IsSuccessStatusCode) { string resContent = response.Content.ReadAsStringAsync().Result; var code2session = _jsonSerializer.Deserialize<Code2Session>(resContent); switch (code2session.errcode) { case 0: string providerKey = code2session.openid; context.Result = await ServerValidate("WeChat", providerKey); break; default:context.Result = new GrantValidationResult( IdentityServer4.Models.TokenRequestErrors.InvalidGrant, "wechat:"+code2session.errmsg); break; } } else context.Result = new GrantValidationResult(IdentityServer4.Models.TokenRequestErrors.InvalidGrant); } readonly DateTime DateTime1970 = new DateTime(1970, 1, 1).ToLocalTime(); /// <summary> /// 服务器验证并输出用户信息,以便自动生成token /// </summary> /// <param name="loginProvider"></param> /// <param name="providerKey"></param> /// <returns></returns> private async Task<GrantValidationResult> ServerValidate(string loginProvider,string providerKey) { var user = await _userManager.FindByLoginAsync(loginProvider, providerKey); if (user == null) return new GrantValidationResult(IdentityServer4.Models.TokenRequestErrors.InvalidGrant); var principal = new ClaimsPrincipal(); List<ClaimsIdentity> claimsIdentity = new List<ClaimsIdentity>(); ClaimsIdentity identity = new ClaimsIdentity(); identity.AddClaim(new Claim("sub", user.Id.ToString())); identity.AddClaim(new Claim("tenantid", user.TenantId.ToString())); identity.AddClaim(new Claim("idp", "local")); identity.AddClaim(new Claim("amr", loginProvider)); long authTime = (long)(DateTime.Now.ToLocalTime() - DateTime1970).TotalSeconds; identity.AddClaim(new Claim("auth_time", authTime.ToString())); claimsIdentity.Add(identity); principal.AddIdentities(claimsIdentity); return new GrantValidationResult(principal); } } }
在HttpApiHostModule.cs 文件中添加注册
public override void PreConfigureServices(ServiceConfigurationContext context) { context.Services.PreConfigure<IIdentityServerBuilder>( builder => { builder.AddExtensionGrantValidator<WeChatGrantValidator>(); }); }
注意此处是在重写的方法PreConfigureServices而不是ConfigureServices中!不然为会报:"error": "unsupported_grant_type"
IdentityServer 认证服务的文件夹中的种子数据添加grantTypes(CreateClientAsync()下)
await CreateClientAsync( "wechat-web", new[] { "IdentityService", "InternalGateway", "WebAppGateway", "BusinessService" }, new[] { "client_credentials", "authorization_code", "wechat_code" } );
认证的类型表中要有相关认证类型数据,
钉钉也可参考本文进行扩展
分类:
abpvnext
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端