You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET Core中实现JWT令牌验证API以防范前端令牌篡改问题

如何在.NET Core中实现JWT令牌验证API以防范前端令牌篡改问题

我完全懂你的顾虑——前端把JWT存在localStorage里确实容易被用户手动篡改,如果前端路由只靠本地令牌判断权限,那恶意修改后就能直接跳转到受保护页面,这绝对是个安全漏洞。下面我就给你实现那个ValidateToken方法,再补几个关键的安全细节,帮你把这块的安全补上。

核心实现:ValidateToken方法的具体代码

首先你得确保项目里引用了Microsoft.IdentityModel.Tokens和System.IdentityModel.Tokens.Jwt这两个NuGet包,然后就可以写验证逻辑了。这个方法的核心是校验JWT的签名有效性(篡改后的令牌签名会和原始签名不匹配,这是最关键的验证点),同时还要校验令牌的发行者、受众、过期时间等核心声明。

using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

public async Task<bool> ValidateToken(string token)
{
    // 空令牌直接返回无效
    if (string.IsNullOrEmpty(token))
        return false;

    // 这里的配置要和你的Identity Server完全一致!
    var tokenValidationParameters = new TokenValidationParameters
    {
        // 你的Identity Server的地址(发行者)
        ValidIssuer = "https://your-identity-server-url",
        // 你的API对应的受众(要和Identity Server里配置的API资源一致)
        ValidAudience = "your-api-resource-name",
        // 签名密钥:如果Identity Server用的是对称密钥,就用这个;非对称的话换成对应的公钥
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your-identity-server-signing-key")),
        // 强制校验签名(核心,防止篡改)
        ValidateIssuerSigningKey = true,
        // 校验发行者
        ValidateIssuer = true,
        // 校验受众
        ValidateAudience = true,
        // 校验令牌过期时间
        ValidateLifetime = true,
        // 允许的时钟偏差(避免服务器时间差导致的过期校验失败)
        ClockSkew = TimeSpan.FromSeconds(30)
    };

    var tokenHandler = new JwtSecurityTokenHandler();
    try
    {
        // 这里会自动完成所有校验:签名、发行者、受众、过期时间等
        ClaimsPrincipal principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken validatedToken);
        
        // 如果你需要额外校验自定义声明,比如jti(令牌ID)或者用户状态,也可以在这里加逻辑
        // 比如检查jti是否在后端的有效令牌列表里(应对用户主动登出的场景)
        // var jti = principal.FindFirstValue(JwtRegisteredClaimNames.Jti);
        // if (!_validTokenCache.Contains(jti)) return false;
        
        return true;
    }
    catch (SecurityTokenException ex)
    {
        // 捕获所有令牌相关的异常:签名无效、令牌过期、发行者不匹配等
        Console.WriteLine($"令牌验证失败:{ex.Message}");
        return false;
    }
    catch (Exception ex)
    {
        // 其他意外异常
        Console.WriteLine($"验证过程出错:{ex.Message}");
        return false;
    }
}

更省心的全局验证方案

其实你不用每个请求都手动调用这个ValidateToken方法,.NET Core已经自带了JWT验证的中间件,配置后所有带[Authorize]属性的API端点都会自动校验令牌,比手动调用更可靠:

  1. 在Program.cs里配置JWT验证服务:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidIssuer = "https://your-identity-server-url",
            ValidAudience = "your-api-resource-name",
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your-identity-server-signing-key")),
            ValidateIssuerSigningKey = true,
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ClockSkew = TimeSpan.FromSeconds(30)
        };
    });

// 别忘了添加授权服务
builder.Services.AddAuthorization();
  1. 在API控制器的受保护方法上加上[Authorize]属性:
[ApiController]
[Route("api/[controller]")]
public class ProtectedController : ControllerBase
{
    [HttpGet("sensitive-data")]
    [Authorize]
    public IActionResult GetSensitiveData()
    {
        // 能走到这里的请求,令牌肯定是有效的
        return Ok(new { Message = "这是只有合法用户才能看到的数据" });
    }
}

额外的安全加固建议

  • 别只靠前端路由守卫:前端的路由控制只能做用户体验优化,所有敏感数据的请求必须经过后端的令牌校验,哪怕前端显示了页面,后端也要拒绝非法令牌的请求。
  • 改用HttpOnly Cookie存储令牌:把JWT存在HttpOnly、Secure的Cookie里,能避免XSS攻击窃取令牌,比localStorage更安全(当然要配置SameSite属性防止CSRF)。
  • 缩短令牌过期时间:给JWT设置较短的过期时间(比如15分钟),配合刷新令牌使用,就算令牌被篡改/窃取,有效时间也很短。
  • 添加自定义校验逻辑:比如在令牌里加入用户的状态声明(比如是否被禁用),验证的时候从数据库查一下用户当前状态,避免令牌有效但用户已经被封禁的情况。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 14:39:33