ASP.NET Core MVC中JWT授权invalid_token问题及Token携带咨询
解决ASP.NET Core MVC JWT授权invalid_token问题及简化Token携带方案
一、排查invalid_token错误的核心步骤
1. 验证JWT配置与生成逻辑的一致性
这是最常见的错误原因,必须确保生成Token时的参数和Program.cs中的验证配置完全匹配:
- 检查
Issuer(发行者):生成Token时指定的Issuer(你的Token中为MyStoreDBDataBase),要和AddJwtBearer配置里TokenValidationParameters的ValidIssuer完全一致。 - 检查
Audience(受众):生成Token的Audience需与ValidAudience完全相同。 - 检查签名密钥:生成Token使用的密钥(如
_configuration["Jwt:SecretKey"]),必须和验证时IssuerSigningKey调用的密钥一致,注意HS256算法要求密钥长度至少16字节。 - 检查签名算法:生成Token用
SecurityAlgorithms.HmacSha256时,验证配置需确保ValidAlgorithms包含该算法(或不指定,默认兼容)。
示例验证配置(Program.cs):
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 }; });
2. 检查Token本身有效性
用JWT解析工具(本地离线解析工具即可)拆解你的Token,确认:
exp(过期时间戳)是否大于当前时间。role等声明是否符合控制器[Authorize]要求(比如控制器用了[Authorize(Roles="Admin")],但Token中role值不符)。
3. 验证EF授权表数据
EF自动生成的AspNetUsers、AspNetRoles、AspNetUserRoles表需有正确关联数据:
- 确认
AspNetUsers表存在UserName为Admin的用户,且密码哈希正确(可通过UserManager.CheckPasswordAsync验证登录密码匹配性)。 - 确认
AspNetRoles表存在Name为Admin的角色。 - 确认
AspNetUserRoles表有Admin用户与Admin角色的关联记录。 - 检查迁移执行情况:运行
Add-Migration InitialCreate和Update-Database命令,确保表结构生成且数据插入成功。
二、简化请求携带Token的方法
1. 前端全局请求拦截器(适配Ajax/Fetch)
封装全局拦截器,自动从localStorage或Cookie读取Token并添加到请求头,无需每个请求手动编写:
// 封装带Token的Fetch方法 const fetchWithToken = async (url, options = {}) => { const token = localStorage.getItem('jwtToken'); options.headers = { ...options.headers, 'Authorization': token ? `Bearer ${token}` : '' }; return await fetch(url, options); }; // 使用示例 fetchWithToken('/Users/Index') .then(res => res.json()) .then(data => console.log(data));
2. MVC视图中用Cookie存储Token(更安全)
登录成功后将Token写入HttpOnly Cookie,再通过全局脚本自动读取并添加到请求头:
// AccountController登录成功后写入Cookie Response.Cookies.Append("jwtToken", token, new CookieOptions { HttpOnly = true, Secure = true, SameSite = SameSiteMode.Strict, Expires = DateTime.UtcNow.AddHours(1) });
前端读取Cookie并拦截请求:
function getCookie(name) { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop().split(';').shift(); } // 全局覆盖Fetch方法,自动携带Token const originalFetch = window.fetch; window.fetch = async function(url, options) { const token = getCookie('jwtToken'); if (token) { options.headers = options.headers || {}; options.headers['Authorization'] = `Bearer ${token}`; } return originalFetch(url, options); };
3. Postman快速测试方案
在Postman中设置环境变量,自动复用Token:
- 登录请求的Tests标签添加脚本,提取Token存入变量:
const response = pm.response.json(); pm.environment.set("jwtToken", response.token);
- 后续请求的Authorization选择Bearer Token,填入
{{jwtToken}}即可自动携带。
内容的提问来源于stack exchange,提问作者CriticalError
相关产品推荐
相关产品推荐

