求基于ASP.NET Core 2.0+Identity+SQL Server的JWT认证登录注册Web API示例
Hey there! Since you're new to ASP.NET Core 2.0 Web API, Identity, and JWT tokens, I'll walk you through a complete, self-contained example that uses SQL Server for the user store, implements registration/login with Identity, and adds JWT authentication. Let's dive in!
First, create a new project using either Visual Studio (select the "ASP.NET Core Web API" template targeting .NET Core 2.0) or the .NET CLI:
dotnet new webapi -n IdentityJwtDemo -f netcoreapp2.0
Add these packages to handle Identity, EF Core with SQL Server, and JWT authentication:
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore dotnet add package Microsoft.EntityFrameworkCore.SqlServer dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer dotnet add package Microsoft.IdentityModel.Tokens dotnet add package System.IdentityModel.Tokens.Jwt
Create a custom user class to extend Identity's default user (add custom fields if needed), then set up the DbContext to work with Identity:
// Models/AppUser.cs using Microsoft.AspNetCore.Identity; public class AppUser : IdentityUser { // Add custom properties like full name public string FullName { get; set; } } // Data/AppDbContext.cs using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; public class AppDbContext : IdentityDbContext<AppUser> { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); // Optional: Customize Identity table names or constraints here } }
Update Startup.cs to wire up the DbContext, Identity, and JWT authentication:
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.IdentityModel.Tokens; using System.Text; public class Startup { public IConfiguration Configuration { get; } public Startup(IConfiguration configuration) { Configuration = configuration; } public void ConfigureServices(IServiceCollection services) { // Connect to SQL Server services.AddDbContext<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); // Add Identity with our custom user services.AddIdentity<AppUser, IdentityRole>() .AddEntityFrameworkStores<AppDbContext>() .AddDefaultTokenProviders(); // Configure JWT settings var jwtSettings = Configuration.GetSection("JwtSettings"); var secretKey = Encoding.ASCII.GetBytes(jwtSettings["SecretKey"]); services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(options => { options.RequireHttpsMetadata = false; // Set to true in production options.SaveToken = true; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = jwtSettings["Issuer"], ValidAudience = jwtSettings["Audience"], IssuerSigningKey = new SymmetricSecurityKey(secretKey) }; }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_0); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseHsts(); } app.UseHttpsRedirection(); // Add authentication middleware BEFORE MVC app.UseAuthentication(); app.UseMvc(); } }
Update appsettings.json with your SQL Server connection string and JWT settings:
{ "ConnectionStrings": { "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=IdentityJwtDemo;Trusted_Connection=True;MultipleActiveResultSets=true" }, "JwtSettings": { "SecretKey": "your-super-secret-key-at-least-16-chars", "Issuer": "IdentityJwtDemoApi", "Audience": "IdentityJwtDemoClients", "TokenExpiryMinutes": 60 } }
Create a controller to handle user registration and JWT token generation:
// Controllers/AuthController.cs using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.IdentityModel.Tokens; using System; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using System.Threading.Tasks; [Route("api/[controller]")] [ApiController] public class AuthController : ControllerBase { private readonly UserManager<AppUser> _userManager; private readonly SignInManager<AppUser> _signInManager; private readonly IConfiguration _configuration; public AuthController(UserManager<AppUser> userManager, SignInManager<AppUser> signInManager, IConfiguration configuration) { _userManager = userManager; _signInManager = signInManager; _configuration = configuration; } // POST: api/Auth/Register [HttpPost("register")] public async Task<IActionResult> Register([FromBody] RegisterModel model) { if (!ModelState.IsValid) return BadRequest(ModelState); var user = new AppUser { UserName = model.Email, Email = model.Email, FullName = model.FullName }; var result = await _userManager.CreateAsync(user, model.Password); if (result.Succeeded) { return Ok(new { Message = "User registered successfully!" }); } foreach (var error in result.Errors) { ModelState.AddModelError(string.Empty, error.Description); } return BadRequest(ModelState); } // POST: api/Auth/Login [HttpPost("login")] public async Task<IActionResult> Login([FromBody] LoginModel model) { if (!ModelState.IsValid) return BadRequest(ModelState); var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, false, false); if (result.Succeeded) { var user = await _userManager.FindByEmailAsync(model.Email); var token = GenerateJwtToken(user); return Ok(new { Token = token }); } return Unauthorized(new { Message = "Invalid email or password" }); } private string GenerateJwtToken(AppUser user) { var jwtSettings = _configuration.GetSection("JwtSettings"); var secretKey = Encoding.ASCII.GetBytes(jwtSettings["SecretKey"]); var claims = new[] { new Claim(JwtRegisteredClaimNames.Sub, user.Email), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(ClaimTypes.NameIdentifier, user.Id), new Claim(ClaimTypes.Name, user.FullName) }; var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims), Expires = DateTime.UtcNow.AddMinutes(Convert.ToDouble(jwtSettings["TokenExpiryMinutes"])), Issuer = jwtSettings["Issuer"], Audience = jwtSettings["Audience"], SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(secretKey), SecurityAlgorithms.HmacSha256Signature) }; var tokenHandler = new JwtSecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); } } // Request models public class RegisterModel { public string FullName { get; set; } public string Email { get; set; } public string Password { get; set; } } public class LoginModel { public string Email { get; set; } public string Password { get; set; } }
Create a controller with an endpoint that requires JWT authentication:
// Controllers/ProtectedController.cs using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; [Route("api/[controller]")] [ApiController] [Authorize] public class ProtectedController : ControllerBase { [HttpGet("user-info")] public IActionResult GetUserInfo() { var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; var fullName = User.FindFirst(ClaimTypes.Name)?.Value; var email = User.FindFirst(ClaimTypes.Email)?.Value; return Ok(new { UserId = userId, FullName = fullName, Email = email, Message = "You've accessed a protected endpoint!" }); } }
- Create and apply database migrations:
dotnet ef migrations add InitialCreate dotnet ef database update
- Run the project:
dotnet run
- Test with tools like Postman or curl:
- Register: POST to
https://localhost:<port>/api/auth/registerwith JSON body containingFullName,Email, andPassword - Login: POST to
https://localhost:<port>/api/auth/loginwithEmailandPasswordto get a JWT token - Access Protected Endpoint: Send a GET request to
https://localhost:<port>/api/protected/user-infowith anAuthorizationheader set toBearer <your-jwt-token>
- Register: POST to
内容的提问来源于stack exchange,提问作者Niteesh Kumar

