ASP.NET中JWT认证接口始终返回401未授权问题求助
问题分析与解决方案
你的核心问题是:默认JwtBearer认证中间件只会从Authorization: Bearer <token>请求头读取令牌,但你把JWT存在了HttpOnly Cookie中,导致认证逻辑找不到令牌,返回401未授权。以下是具体修复步骤:
1. 修改JwtBearer配置,支持从Cookie读取令牌
在Program.cs的AddJwtBearer配置中,添加事件逻辑,让中间件从指定Cookie中提取令牌:
builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("very-safe-secret")), // 你当前的令牌未配置Issuer和Audience,需关闭这两项验证,否则会触发认证失败 ValidateIssuer = false, ValidateAudience = false, AuthenticationType = "Bearer" }; // 添加从Cookie读取令牌的逻辑 options.Events = new JwtBearerEvents { OnMessageReceived = context => { // 这里的"jwt"要和你存入Cookie时的名称完全一致 context.Token = context.Request.Cookies["jwt"]; return Task.CompletedTask; } }; });
2. 优化JWT生成逻辑(可选但推荐)
你的JWTokenHandler未设置令牌过期时间,建议添加避免令牌永久有效:
public JWTokenHandler(string payload) { _tokenHandler = new JwtSecurityTokenHandler(); _key = Encoding.ASCII.GetBytes("very-safe-secret"); _tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new[] { new Claim("payload", payload) }), // 设置令牌1小时后过期 Expires = DateTime.UtcNow.AddHours(1), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(_key), SecurityAlgorithms.HmacSha256Signature) }; }
3. 正确存入HttpOnly Cookie的示例
在你的登录接口中,生成令牌后按以下方式存入Cookie:
[HttpPost("login")] public IActionResult Login(string username, string password) { // 这里替换为你的用户验证逻辑 bool isValidUser = true; if (!isValidUser) return Unauthorized(); var tokenHandler = new JWTokenHandler("user-payload-data"); var token = tokenHandler.generateToken(); // 存入HttpOnly Cookie Response.Cookies.Append("jwt", token, new CookieOptions { HttpOnly = true, Secure = !builder.Environment.IsDevelopment(), // 生产环境强制HTTPS SameSite = SameSiteMode.Strict, Expires = DateTime.UtcNow.AddHours(1) // 与令牌过期时间保持一致 }); return Ok("登录成功"); }
4. Postman测试步骤
- 调用登录接口,Postman会自动保存返回的HttpOnly Cookie
- 直接调用
api/Character的Get接口,无需手动添加Authorization头,认证中间件会自动从Cookie读取令牌完成授权
内容的提问来源于stack exchange,提问作者jimmyakiraly
相关产品推荐
相关产品推荐

