.NET Core JWT 登录授权完整实战教程

7 阅读3分钟

JWT(JSON Web Token)是无状态的登录授权方案,适合前后端分离、微服务项目,无需存储 Session,仅靠 Token 完成身份验证。

下面带你一步步实现 .NET 6/7/8 + JWT 登录、颁发 Token、接口授权验证


一、核心流程

  1. 用户输入账号密码 → 后端验证
  2. 验证通过 → 生成 JWT Token 返回给前端
  3. 前端存储 Token(localStorage/cookie)
  4. 前端请求接口时 → 请求头携带 Authorization: Bearer Token
  5. 后端验证 Token 有效性 → 允许/拒绝访问

二、环境准备

  1. 创建 ASP.NET Core Web API 项目
  2. 安装 JWT 必需 NuGet 包:
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer

三、完整实现代码

1. 配置 JWT 参数(appsettings.json)

{
  "JwtSettings": {
    "SecretKey": "YourLongSecretKeyHere_1234567890abcdef", // 密钥(越长越安全)
    "Issuer": "MyServer", // 签发者
    "Audience": "MyClient", // 接收者
    "ExpireMinutes": 60 // Token 过期时间(分钟)
  }
}

2. 创建 JWT 配置实体类

namespace JwtDemo
{
    public class JwtSettings
    {
        public string SecretKey { get; set; } = string.Empty;
        public string Issuer { get; set; } = string.Empty;
        public string Audience { get; set; } = string.Empty;
        public int ExpireMinutes { get; set; }
    }
}

3. Program.cs 注册 JWT 认证服务(核心配置)

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

// 1. 读取 JWT 配置
var jwtSettings = builder.Configuration.GetSection("JwtSettings").Get<JwtSettings>();
builder.Services.AddSingleton(jwtSettings); // 注入配置

// 2. 添加控制器
builder.Services.AddControllers();

// 3. 注册 JWT 认证
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true, // 验证签发者
            ValidateAudience = true, // 验证接收者
            ValidateLifetime = true, // 验证过期时间
            ValidateIssuerSigningKey = true, // 验证签名密钥
            ValidIssuer = jwtSettings.Issuer,
            ValidAudience = jwtSettings.Audience,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey))
        };
    });

var app = builder.Build();

// 4. 启用认证 + 授权中间件(顺序不能错!)
app.UseAuthentication(); // 先认证
app.UseAuthorization();  // 后授权

app.MapControllers();
app.Run();

4. 创建登录接口 + Token 生成服务

登录请求模型

namespace JwtDemo.Models
{
    public class LoginRequest
    {
        public string UserName { get; set; } = string.Empty;
        public string Password { get; set; } = string.Empty;
    }
}

登录控制器(生成 JWT Token)

using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using JwtDemo.Models;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace JwtDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class AccountController : ControllerBase
    {
        private readonly JwtSettings _jwtSettings;

        // 注入 JWT 配置
        public AccountController(JwtSettings jwtSettings)
        {
            _jwtSettings = jwtSettings;
        }

        /// <summary>
        /// 登录接口:验证账号密码,生成 Token
        /// </summary>
        [HttpPost("login")]
        public IActionResult Login(LoginRequest request)
        {
            // 1. 模拟数据库验证账号密码(实际项目替换为真实校验)
            if (request.UserName != "admin" || request.Password != "123456")
            {
                return Unauthorized("账号或密码错误");
            }

            // 2. 创建用户声明(存储用户信息:ID、角色、权限等)
            var claims = new[]
            {
                new Claim(ClaimTypes.Name, request.UserName),
                new Claim(ClaimTypes.Role, "Admin"), // 角色(用于权限控制)
                new Claim("UserId", "1001") // 自定义字段
            };

            // 3. 生成签名密钥
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            // 4. 创建 JWT Token
            var token = new JwtSecurityToken(
                issuer: _jwtSettings.Issuer,
                audience: _jwtSettings.Audience,
                claims: claims,
                expires: DateTime.Now.AddMinutes(_jwtSettings.ExpireMinutes),
                signingCredentials: creds
            );

            // 5. 返回 Token 字符串
            var tokenStr = new JwtSecurityTokenHandler().WriteToken(token);
            return Ok(new
            {
                Token = tokenStr,
                ExpireTime = _jwtSettings.ExpireMinutes
            });
        }
    }
}

5. 测试授权接口

using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using JwtDemo.Models;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.AspNetCore.Authorization;
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
    /// <summary>
    /// 无需授权:公开接口
    /// </summary>
    [HttpGet("public")]
    public IActionResult Public()
    {
        return Ok("这是公开接口,任何人可访问");
    }

    /// <summary>
    /// 需要授权:私有接口
    /// </summary>
    [HttpGet("private")]
    [Authorize] // 核心:添加此特性表示需要登录授权
    public IActionResult Private()
    {
        // 获取当前登录用户信息
        var userName = User.Identity?.Name;
        return Ok($"这是私有接口,已授权!当前用户:{userName}");
    }

    /// <summary>
    /// 角色授权:仅 Admin 可访问
    /// </summary>
    [HttpGet("admin")]
    [Authorize(Roles = "Admin")]
    public IActionResult AdminOnly()
    {
        return Ok("管理员专属接口");
    }
}

四、测试流程(Postman/Swagger)

  1. 运行项目 → 打开 Swagger
  2. 调用 api/Account/login,传入账号密码:
    { "userName": "admin", "password": "123456" }
    
  3. 复制返回的 Token
  4. 调用 api/Test/private
    • 请求头添加:Authorization: Bearer 你的Token
    • 携带 Token → 访问成功
    • 不携带 Token → 返回 401 未授权

五、关键知识点

  1. [Authorize]:标记需要授权的接口/控制器
  2. [AllowAnonymous]:标记公开接口(跳过授权)
  3. Claim:存储用户信息(用户ID、角色、权限),可自定义
  4. 无状态:Token 存储所有用户信息,服务器无需保存会话
  5. 安全性:密钥必须保密,Token 过期时间不宜过长

六、常见问题

  1. 401 未授权
    • 未携带 Authorization 请求头
    • Token 过期/错误
    • 密钥、签发者配置不匹配
  2. Token 被篡改
    • 服务器会自动验证签名,篡改后直接失效
  3. 跨域问题
    • 前端调用需配置 CORS 跨域

总结

  1. 安装 JWT 包 → 配置 JWT 参数 → 注册认证服务
  2. 登录验证 → 生成 JWT Token 返回前端
  3. 接口添加 [Authorize] → 实现授权验证
  4. 支持角色权限自定义声明无状态认证