C# .NET 6 WebAPI 对接微信小程序:3类接口设计与JWT鉴权实战 C# .NET 6 WebAPI 对接微信小程序3类接口设计与JWT鉴权实战当开发者需要为微信小程序构建稳定可靠的后端服务时C# .NET 6 WebAPI凭借其高性能和丰富的生态成为理想选择。本文将深入探讨三种典型接口的设计实现并构建完整的JWT鉴权体系为缺乏小程序联调经验的.NET开发者提供可直接复用的工程化解决方案。1. 环境准备与基础配置在开始接口开发前需要完成基础环境的搭建。首先确保已安装.NET 6 SDK和Visual Studio 2022或Rider等IDE。创建新项目时选择ASP.NET Core Web API模板并勾选启用OpenAPI支持dotnet new webapi -n WeChatMiniAppApi --framework net6.0微信小程序要求所有网络请求必须使用HTTPS协议因此在Program.cs中需强制启用HTTPS重定向app.UseHttpsRedirection();小程序后端接口的典型配置参数如下表所示配置项示例值说明BaseUrlhttps://api.yourdomain.com已备案的HTTPS域名RequestTimeout30000微信请求超时(毫秒)MaxRequestBodySize20971520文件上传最大支持20MBCORS PolicyWeChatPolicy跨域策略名称配置微信小程序合法域名时需在微信公众平台将API域名加入request合法域名列表。同时配置开发环境的appsettings.Development.json{ WeChatSettings: { AppId: wx你的小程序appid, AppSecret: 你的小程序appsecret } }2. JWT鉴权体系实现微信小程序推荐使用自定义登录态维护用户身份JWT(JSON Web Token)因其无状态特性成为首选方案。首先安装必要的NuGet包dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer dotnet add package System.IdentityModel.Tokens.Jwt在Program.cs中配置JWT认证服务builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options { options.TokenValidationParameters new TokenValidationParameters { ValidateIssuer true, ValidIssuer builder.Configuration[Jwt:Issuer], ValidateAudience true, ValidAudience builder.Configuration[Jwt:Audience], ValidateLifetime true, IssuerSigningKey new SymmetricSecurityKey( Encoding.UTF8.GetBytes(builder.Configuration[Jwt:SecretKey])), ValidateIssuerSigningKey true, ClockSkew TimeSpan.Zero // 严格校验过期时间 }; });创建JwtHelper工具类处理token生成public static class JwtHelper { public static string GenerateToken(string openId, IConfiguration config) { var claims new[] { new Claim(JwtRegisteredClaimNames.Sub, openId), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) }; var key new SymmetricSecurityKey( Encoding.UTF8.GetBytes(config[Jwt:SecretKey])); var creds new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token new JwtSecurityToken( issuer: config[Jwt:Issuer], audience: config[Jwt:Audience], claims: claims, expires: DateTime.Now.AddDays(7), signingCredentials: creds); return new JwtSecurityTokenHandler().WriteToken(token); } }注意实际生产环境中应考虑使用分布式缓存存储token黑名单实现更灵活的身份控制3. 用户登录接口设计微信小程序登录流程涉及三方交互小程序端、开发者服务器和微信接口服务。典型登录接口实现如下[ApiController] [Route(api/[controller])] public class AuthController : ControllerBase { private readonly IHttpClientFactory _httpClient; private readonly IConfiguration _config; public AuthController(IHttpClientFactory httpClient, IConfiguration config) { _httpClient httpClient; _config config; } [HttpPost(login)] public async TaskIActionResult Login([FromBody] LoginRequest request) { // 1. 校验code有效性 var client _httpClient.CreateClient(); var url $https://api.weixin.qq.com/sns/jscode2session? $appid{_config[WeChatSettings:AppId]} $secret{_config[WeChatSettings:AppSecret]} $js_code{request.Code} grant_typeauthorization_code; var response await client.GetFromJsonAsyncWeChatSessionResponse(url); if (string.IsNullOrEmpty(response.OpenId)) return BadRequest(微信登录失败); // 2. 创建或更新用户记录 var user await _userRepository.FindOrCreateAsync(response.OpenId); // 3. 生成JWT var token JwtHelper.GenerateToken(response.OpenId, _config); return Ok(new LoginResponse { Token token, UserInfo new UserDto(user) }); } }登录流程中涉及的关键DTO定义public record LoginRequest(string Code); public record WeChatSessionResponse(string OpenId, string SessionKey, string UnionId); public record LoginResponse(string Token, UserDto UserInfo);4. 数据获取接口实现数据接口需要同时考虑安全性和性能优化。以下是带分页的商品列表接口示例[Authorize] [HttpGet(products)] public async TaskIActionResult GetProducts([FromQuery] ProductQuery query) { // 1. 参数校验 if (query.PageSize 100) return BadRequest(单页数量不能超过100); // 2. 从JWT中获取用户身份 var openId User.FindFirstValue(JwtRegisteredClaimNames.Sub); // 3. 构建查询条件 var filter new ProductFilter { CategoryId query.CategoryId, MinPrice query.MinPrice, MaxPrice query.MaxPrice, Keywords query.Keywords }; // 4. 分页查询 var (products, total) await _productService.GetPagedListAsync( filter, query.PageIndex, query.PageSize); // 5. 返回标准化响应 return Ok(new PagedResultProductDto( products.Select(p new ProductDto(p)), query.PageIndex, query.PageSize, total)); }为提高接口安全性建议实现以下防护措施参数签名验证防止参数篡改请求频率限制防止暴力请求SQL注入防护使用参数化查询敏感数据脱敏如手机号中间四位替换为*5. 文件上传接口设计微信小程序常见的文件上传场景包括用户头像、反馈图片等。以下是支持多文件上传的接口实现[Authorize] [HttpPost(upload)] [RequestSizeLimit(20 * 1024 * 1024)] // 20MB限制 public async TaskIActionResult UploadFiles(ListIFormFile files) { var openId User.FindFirstValue(JwtRegisteredClaimNames.Sub); var result new ListUploadResult(); foreach (var file in files) { // 1. 文件类型校验 var ext Path.GetExtension(file.FileName).ToLowerInvariant(); if (!_allowedExtensions.Contains(ext)) { result.Add(new UploadResult { FileName file.FileName, Success false, Message 不支持的文件类型 }); continue; } // 2. 生成唯一文件名 var newFileName ${Guid.NewGuid()}{ext}; var savePath Path.Combine(_env.WebRootPath, uploads, newFileName); // 3. 保存文件 await using var stream new FileStream(savePath, FileMode.Create); await file.CopyToAsync(stream); // 4. 记录上传结果 result.Add(new UploadResult { FileName file.FileName, FileUrl $/uploads/{newFileName}, FileSize file.Length, Success true }); } return Ok(result); }文件上传接口的关键配置参数参数推荐值说明MaxRequestBodySize20971520Kestrel最大请求体MultipartBodyLengthLimit20971520多部分表单限制FileSizeLimit5242880单个文件最大5MBAllowedExtensions.jpg,.png,.gif允许的扩展名6. 小程序端请求封装为统一处理鉴权和错误建议在小程序端封装wx.requestconst request (url, method, data) { return new Promise((resolve, reject) { const token wx.getStorageSync(token) wx.request({ url: https://your-api-domain.com${url}, method: method, data: data, header: { Content-Type: application/json, Authorization: token ? Bearer ${token} : }, success: (res) { if (res.statusCode 401) { // token过期处理 wx.navigateTo({ url: /pages/login/login }) return } if (res.data.code ! 0) { wx.showToast({ title: res.data.message, icon: none }) reject(res.data) return } resolve(res.data.data) }, fail: (err) { wx.showToast({ title: 网络错误, icon: none }) reject(err) } }) }) } // 使用示例 const fetchProducts async (params) { return request(/api/products, GET, params) }7. 异常处理与日志记录完善的异常处理机制能显著提升接口可靠性。在.NET 6中配置全局异常处理// Program.cs app.UseExceptionHandler(appError { appError.Run(async context { context.Response.ContentType application/json; var contextFeature context.Features.GetIExceptionHandlerFeature(); if (contextFeature ! null) { // 记录异常日志 _logger.LogError(contextFeature.Error, 全局异常捕获); // 构造标准化错误响应 await context.Response.WriteAsync(new ErrorDetails { StatusCode context.Response.StatusCode, Message contextFeature.Error is BusinessException ? contextFeature.Error.Message : 系统异常 }.ToString()); } }); });建议将日志记录到文件的同时接入APM工具如Application Insights实现请求链路追踪性能指标监控异常告警通知依赖调用分析8. 性能优化实践针对小程序场景的高并发特点可采用以下优化策略缓存策略示例[HttpGet(categories)] [ResponseCache(Duration 3600)] // 客户端缓存1小时 public async TaskIActionResult GetCategories() { var cacheKey product_categories; if (!_cache.TryGetValue(cacheKey, out ListCategory categories)) { categories await _categoryService.GetAllAsync(); _cache.Set(cacheKey, categories, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromHours(1))); } return Ok(categories); }数据库查询优化技巧使用AsNoTracking()避免不必要的变更跟踪通过Select只查询必要字段合理配置索引特别是高频查询条件对大数据集使用分页查询异步编程规范Controller方法全部使用async/await避免.Result或.Wait()导致的死锁长时间运行任务使用BackgroundServiceIO密集型操作配置合理的超时时间9. 安全加固措施除JWT鉴权外还需实施以下安全防护防XSS攻击services.AddControllers(options { options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()); });CSRF防护配置builder.Services.AddAntiforgery(options { options.HeaderName X-CSRF-TOKEN; options.Cookie.SecurePolicy CookieSecurePolicy.Always; });敏感数据保护// 配置数据保护API builder.Services.AddDataProtection() .PersistKeysToFileSystem(new DirectoryInfo(/path/to/keys)) .SetApplicationName(WeChatMiniApp) .ProtectKeysWithCertificate(certificate);10. 部署与监控推荐使用Docker容器化部署示例DockerfileFROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY [WeChatMiniAppApi.csproj, .] RUN dotnet restore WeChatMiniAppApi.csproj COPY . . RUN dotnet build WeChatMiniAppApi.csproj -c Release -o /app/build FROM build AS publish RUN dotnet publish WeChatMiniAppApi.csproj -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --frompublish /app/publish . ENTRYPOINT [dotnet, WeChatMiniAppApi.dll]关键监控指标应包括接口响应时间P99错误率与异常统计JWT签发/验证性能数据库查询效率外部API调用成功率11. 接口测试策略采用分层测试策略确保接口质量单元测试示例[Fact] public void GenerateToken_ShouldReturnValidJwt() { // Arrange var config new ConfigurationBuilder() .AddInMemoryCollection(new Dictionarystring, string { [Jwt:SecretKey] test_key_1234567890, [Jwt:Issuer] test_issuer, [Jwt:Audience] test_audience }) .Build(); // Act var token JwtHelper.GenerateToken(test_openid, config); // Assert Assert.NotNull(token); Assert.NotEmpty(token); }集成测试要点测试带鉴权的API访问验证微信code交换流程文件上传大小限制测试并发请求压力测试错误参数边界测试12. 实际项目经验分享在电商类小程序项目中我们遇到了购物车高并发更新的挑战。最终解决方案是使用Redis分布式锁控制并发采用乐观并发控制处理冲突客户端实现本地缓存减少请求重要操作添加二次确认另一个教育类小程序中视频上传接口经过以下优化分片上传支持断点续传功能OSS直传方案上传进度实时反馈对于需要更高安全要求的金融类小程序我们额外实现了接口调用白名单请求参数签名敏感操作短信验证操作日志审计