目录一、先搞懂JWT 是什么生活类比 核心流程1. 生活类比JWT 景区电子门票2. JWT 核心认证流程图3. 核心价值二、第一步项目配置与 Nuget 包引用1. 环境要求2. 安装 Nuget 包两种方式方式 1Nuget 包管理器方式 2程序包管理器控制台方式 3.NET CLI 命令三、第二步appsettings.json 配置 JWT 核心参数四、第三步Program.cs 注册 JWT 认证服务核心代码五、第四步编写 JWT 令牌生成工具类六、第五步编写登录接口 受保护接口1. 登录接口无需认证生成 Token2. 受保护接口需要 JWT 认证才能访问七、高频踩坑大全90% 的新手都栽过1. 中间件顺序错误最常见2. JWT 密钥太短 / 泄露3. Issuer/Audience 前后端不一致4. 令牌过期 / 服务器时间不同步5. 前端请求头格式错误6. 忘记注册认证服务八、测试验证Postman/Swagger总结在前后端分离成为主流的今天传统的 Session/Cookie 认证已经力不从心 —— 跨域、分布式、移动端适配全是痛点。而JWTJSON Web Token 就是解决这些问题的「万能钥匙」今天这篇专栏我会手把手带你完成ASP.NET Core JWT 认证完整配置从 Nuget 引用、代码编写到高频踩坑全解析用生活类比让你秒懂新手也能直接 CV 跑通一、先搞懂JWT 是什么生活类比 核心流程1. 生活类比JWT 景区电子门票传统 Session你去景区买票工作人员把你的信息记在本子上你只拿一个编号每次进门都要查本子服务器存储状态JWT 认证景区给你一张加密电子票上面写着你的身份、有效期、权限票自己拿着进门时工作人员扫码验证票里自带信息服务器不存储。2. JWT 核心认证流程图否是否是前端用户输入账号密码后端验证账号密码正确性验证通过返回错误账号密码无效后端生成JWT令牌返回给前端前端存储TokenLocalStorage/Cookie前端请求接口请求头携带Authorization: Bearer Token后端验证JWT令牌合法性/有效期验证通过返回401未授权授权访问接口返回数据3. 核心价值1.无状态服务器不存储用户信息分布式部署无压力2.跨域支持完美适配前后端分离、小程序、APP3.安全可控加密签名、过期时间、权限声明全自定义。二、第一步项目配置与 Nuget 包引用1. 环境要求框架ASP.NET Core 6/7/8本文以.NET 6 为例核心包Microsoft.AspNetCore.Authentication.JwtBearer官方 JWT 认证中间件2. 安装 Nuget 包两种方式方式 1Nuget 包管理器VS 中右键项目 → 管理 Nuget 程序包 → 浏览 → 搜索**Microsoft.AspNetCore.Authentication.JwtBearer ** → 安装最新稳定版。方式 2程序包管理器控制台Install-Package Microsoft.AspNetCore.Authentication.JwtBearer方式 3.NET CLI 命令dotnetaddpackage Microsoft.AspNetCore.Authentication.JwtBearer三、第二步appsettings.json 配置 JWT 核心参数我们把 JWT 的密钥、颁发者、过期时间等配置写在配置文件方便后期修改。{Logging:{LogLevel:{Default:Information,Microsoft.AspNetCore:Warning}},// JWT配置节点JwtSettings:{SecretKey:LongLongSecretKey1234567890ABCDEF,// 密钥越长越安全至少16位Issuer:MyBackendServer,// 令牌颁发者你的后端服务Audience:MyFrontendClient,// 令牌接收者你的前端ExpiresMinutes:60// 令牌过期时间60分钟},AllowedHosts:*}✅ 小节重点SecretKey绝对不能泄露相当于你的令牌「签名钥匙」泄露后任何人都能伪造令牌ExpiresMinutes不建议设置过长建议 30~120 分钟配合刷新 Token 使用3.Issuer 和 Audience前后端必须保持一致否则验证失败。四、第三步Program.cs 注册 JWT 认证服务核心代码这是 JWT 生效的核心步骤我们需要在 Program.cs 中注册认证、授权服务并启用中间件。完整代码.NET 6 顶级语句usingMicrosoft.AspNetCore.Authentication.JwtBearer;usingMicrosoft.IdentityModel.Tokens;usingSystem.Text;varbuilderWebApplication.CreateBuilder(args);// 1. 添加控制器服务builder.Services.AddControllers();// 2. 从配置文件读取JWT参数varjwtSettingsbuilder.Configuration.GetSection(JwtSettings);varsecretKeyjwtSettings[SecretKey];varissuerjwtSettings[Issuer];varaudiencejwtSettings[Audience];varexpiresMinutesConvert.ToDouble(jwtSettings[ExpiresMinutes]);// 3. 注册JWT认证服务 ★核心代码★builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options{// 配置令牌验证参数options.TokenValidationParametersnewTokenValidationParameters{// 验证颁发者ValidateIssuertrue,ValidIssuerissuer,// 验证接收者ValidateAudiencetrue,ValidAudienceaudience,// 验证过期时间ValidateLifetimetrue,// 验证签名密钥ValidateIssuerSigningKeytrue,IssuerSigningKeynewSymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)),// 过期时间容错值防止服务器时间不同步ClockSkewTimeSpan.Zero};// 可选配置JWT认证失败的自定义返回信息options.EventsnewJwtBearerEvents{OnChallengecontext{context.Response.StatusCodeStatusCodes.Status401Unauthorized;context.Response.ContentTypeapplication/json;varresultnew{code401,message未授权请先登录获取Token};context.Response.WriteAsync(System.Text.Json.JsonSerializer.Serialize(result));returnTask.CompletedTask;}};});// 4. 注册授权服务builder.Services.AddAuthorization();varappbuilder.Build();// 中间件执行顺序必须是 认证 → 授权 → 路由app.UseHttpsRedirection();// ★ 顺序绝对不能错 ★app.UseAuthentication();// 启用认证第一步app.UseAuthorization();// 启用授权第二步app.MapControllers();app.Run();✅ 小节重点中间件顺序UseAuthentication 必须在 UseAuthorization 之前先认证身份再判断权限ClockSkew设置为 0严格校验过期时间避免令牌超时仍能使用自定义 OnChallenge让认证失败返回友好 JSON而非默认的 HTML 页面。五、第四步编写 JWT 令牌生成工具类我们封装一个通用工具类用于用户登录成功后生成 JWT 令牌。usingMicrosoft.IdentityModel.Tokens;usingSystem.IdentityModel.Tokens.Jwt;usingSystem.Security.Claims;usingSystem.Text;namespaceJwtDemo.Utils{/// summary/// JWT令牌生成工具类/// /summarypublicstaticclassJwtTokenHelper{/// summary/// 生成JWT Token/// /summary/// param nameconfiguration配置文件/param/// param nameuserId用户ID/param/// param nameuserName用户名/param/// param namerole用户角色admin/user/param/// returnsJWT令牌/returnspublicstaticstringCreateToken(IConfigurationconfiguration,stringuserId,stringuserName,stringrole){// 读取JWT配置varjwtSettingsconfiguration.GetSection(JwtSettings);varsecretKeyjwtSettings[SecretKey];varissuerjwtSettings[Issuer];varaudiencejwtSettings[Audience];varexpiresMinutesConvert.ToDouble(jwtSettings[ExpiresMinutes]);// 1. 创建用户声明存储用户信息如ID、角色、权限varclaimsnew[]{newClaim(ClaimTypes.NameIdentifier,userId),// 用户IDnewClaim(ClaimTypes.Name,userName),// 用户名newClaim(ClaimTypes.Role,role),// 用户角色newClaim(CustomInfo,自定义业务数据)// 自定义声明};// 2. 创建密钥对象varkeynewSymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));// 3. 创建签名凭证varcredentialsnewSigningCredentials(key,SecurityAlgorithms.HmacSha256);// 4. 生成JWT令牌vartokennewJwtSecurityToken(issuer:issuer,audience:audience,claims:claims,expires:DateTime.Now.AddMinutes(expiresMinutes),// 过期时间signingCredentials:credentials);// 5. 生成最终的Token字符串returnnewJwtSecurityTokenHandler().WriteToken(token);}}}✅ 小节重点Claim声明存储在令牌里的用户信息相当于门票上的「身份信息」角色声明用于后续权限控制必须用ClaimTypes.Role类型令牌加密固定使用HmacSha256算法安全性最高。六、第五步编写登录接口 受保护接口1. 登录接口无需认证生成 TokenusingMicrosoft.AspNetCore.Mvc;usingJwtDemo.Utils;namespaceJwtDemo.Controllers{[Route(api/[controller])][ApiController]publicclassLoginController:ControllerBase{privatereadonlyIConfiguration_configuration;// 注入配置文件publicLoginController(IConfigurationconfiguration){_configurationconfiguration;}/// summary/// 用户登录验证账号密码生成JWT Token/// /summary[HttpPost]publicIActionResultLogin(stringuserName,stringpassword){// 模拟数据库验证账号密码实际项目替换为真实校验if(userNameadminpassword123456){// 登录成功生成TokenvartokenJwtTokenHelper.CreateToken(_configuration,1001,userName,admin);returnOk(new{code200,message登录成功,tokentoken,expiresIn60// 过期时间分钟});}// 登录失败returnOk(new{code400,message账号或密码错误});}}}2. 受保护接口需要 JWT 认证才能访问usingMicrosoft.AspNetCore.Authorization;usingMicrosoft.AspNetCore.Mvc;namespaceJwtDemo.Controllers{[Route(api/[controller])][ApiController]// 全局添加[Authorize]整个控制器需要认证[Authorize]publicclassUserController:ControllerBase{/// summary/// 获取用户信息必须携带有效Token才能访问/// /summary[HttpGet(info)]publicIActionResultGetUserInfo(){// 从JWT令牌中读取用户信息varuserIdUser.FindFirst(ClaimTypes.NameIdentifier)?.Value;varuserNameUser.Identity?.Name;varroleUser.FindFirst(ClaimTypes.Role)?.Value;returnOk(new{code200,message获取用户信息成功,datanew{userId,userName,role}});}/// summary/// 仅管理员可访问角色权限校验/// /summary[HttpGet(admin)][Authorize(Rolesadmin)]publicIActionResultAdminApi(){returnOk(new{code200,message管理员接口访问成功});}}}✅ 小节重点1.[AllowAnonymous]跳过认证登录接口必须加2.[Authorize]需要认证才能访问3.[Authorize(Roles “admin”)]角色授权仅指定角色可访问。七、高频踩坑大全90% 的新手都栽过1. 中间件顺序错误最常见❌ 错误app.UseAuthorization() 在 app.UseAuthentication() 之前✅ 正确先认证后授权顺序不可逆。2. JWT 密钥太短 / 泄露❌ 错误密钥长度 16 位或硬编码在代码中提交到 Git✅ 正确密钥≥16 位存配置文件严格保密。3. Issuer/Audience 前后端不一致❌ 错误后端配置Issuer“A”前端校验Issuer“B”✅ 正确前后端配置必须完全一致。4. 令牌过期 / 服务器时间不同步❌ 错误未设置ClockSkew导致令牌明明没过期却验证失败✅ 正确设置ClockSkew TimeSpan.Zero。5. 前端请求头格式错误❌ 错误Authorization: Token xxxxx 或 直接写 Token✅ 正确Authorization: Bearer 你的JWT令牌Bearer 空格 必须有。6. 忘记注册认证服务❌ 错误只写UseAuthentication没写AddAuthentication✅ 正确先注册服务再启用中间件。八、测试验证Postman/Swagger1.运行项目访问/api/Login输入账号密码获取 Token2.访问/api/User/info请求头添加Authorization: Bearer 你的Token3.验证结果携带有效 Token → 返回 200 用户信息无 Token / 无效 Token → 返回 401 未授权普通用户访问管理员接口 → 返回 403 禁止访问。 结尾互动今天的 JWT 认证全套配置就讲完啦从代码 CV 到避坑新手也能直接落地前后端分离项目互动问题你在项目中用的是 JWT 还是 Session 认证你还遇到过哪些 JWT 踩坑问题评论区告诉我总结1.JWT 前后端分离必备认证方案无状态、跨域、安全2.核心三步安装 Nuget 包→注册认证服务→生成 / 验证令牌3.避坑核心中间件顺序、密钥安全、请求头格式三大关键点4.代码全量可直接 CV 运行适合.NET6/7/8 所有版本我是编程老伙计关注我下期带来 JWT 进阶实战咱们评论区见