一.配置
1.Startup.cs配置代码
using CRUD3.Config;
using CRUD3.Models;
using CRUD3.Services;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Security.Claims;
using System.Security.Cryptography;
namespace CRUD3
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
// Add your services here
string connectionString = Configuration.GetConnectionString("DefaultConnection");
services.AddScoped<IUserRespository,UserRespository>();
services.AddScoped<IUserservice, UserService>();
//swager
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Your API", Version = "v1" });
});
//database
services.AddDbContext<DemoContext>(options =>
options.UseMySql
(connectionString, ServerVersion.AutoDetect(connectionString))
);
// 生成 RSA 密钥对
RSA rsa = RSA.Create(2048);
var privateKey = rsa;
var publicKey = rsa.ExportRSAPublicKey();
// 将密钥保存到服务中,以便后续使用
services.AddSingleton(privateKey);
services.AddSingleton(publicKey);
// 配置 JWT 认证
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new RsaSecurityKey(privateKey)
};
});
//添加自定义接口访问权限 在接口上加[Authorize(Policy = "RequireTest1")]
services.AddAuthorization(options =>
{
options.AddPolicy("admin", policy =>
{
policy.RequireAuthenticatedUser(); // 用户必须经过身份验证
policy.RequireClaim(ClaimTypes.Name, "test1"); // 用户必须具有指定的声明(即 name 必须为 "test1")
});
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Your API V1");
});
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
// 添加全局异常处理中间件
app.UseGlobalExceptionHandler();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
//添加身份验证中间件
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
2.Program.cs配置代码
namespace CRUD3;
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
3.统一返回R类
using CRUD3.Models;
namespace CRUD3.Commons
{
public class R<T>
{
public int Code { get; set; } // 编码:1成功,0和其它数字为失败
public string Msg { get; set; } // 错误信息
public T Data { get; set; } // 数据
public Dictionary<string, object> Map { get; set; } = new Dictionary<string, object>(); // 动态数据
public static R<T> Success(T data)
{
return new R<T> { Data = data, Code = 1 };
}
public static R<T> Error(string msg)
{
return new R<T> { Msg = msg, Code = 0 };
}
public R<T> Add(string key, object value)
{
this.Map[key] = value;
return this;
}
internal R<User> Success(User user)
{
throw new NotImplementedException();
}
}
}
4.全局异常配置类
namespace CRUD3.Config
{
public class GlobalExceptionHandlerMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<GlobalExceptionHandlerMiddleware> _logger;
public GlobalExceptionHandlerMiddleware(RequestDelegate next, ILogger<GlobalExceptionHandlerMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
_logger.LogError(ex, "An unhandled exception has occurred.");
// 处理异常并返回友好的错误响应给客户端
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync("An unexpected error occurred. Please try again later.");
}
}
}
public static class GlobalExceptionHandlerMiddlewareExtensions
{
public static IApplicationBuilder UseGlobalExceptionHandler(this IApplicationBuilder builder)
{
return builder.UseMiddleware<GlobalExceptionHandlerMiddleware>();
}
}
}
5.appsettings.json配置
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=demo1;User=root;Password=123456;"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
6.Models里的DemoContext配置
using Microsoft.EntityFrameworkCore;
namespace CRUD3.Models
{
public class DemoContext : DbContext
{
public DbSet<User> Users { get; set; }
public DemoContext(DbContextOptions<DemoContext> options)
:base(options)
{
}
}
}
二.Models
namespace CRUD3.Models
{
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Pwd { get; set; }
}
}
namespace CRUD3.Models
{
public interface IUserRespository
{
void AddUser(User user);
void DeleteUser(int id);
void UpdateUser(User user);
User GetUserById(int id);
User GetUserByName(string name);
IEnumerable<User> GetAllUsers();
User Login(string name, string pwd);
}
}
namespace CRUD3.Models
{
public class UserRespository : IUserRespository
{
public readonly DemoContext _context;
public UserRespository(DemoContext context)
{
_context = context;
}
public void AddUser(User user)
{
_context.Users.Add(user);
_context.SaveChanges();
}
public void DeleteUser(int id)
{
var user = _context.Users.FirstOrDefault(u=>u.Id== id);
_context.Users.Remove(user);
_context.SaveChanges();
}
public void UpdateUser(User user)
{
var user1=_context.Users.FirstOrDefault(u=>u.Id== user.Id);
_context.Entry(user1).CurrentValues.SetValues(user);
_context.SaveChanges();
}
public User GetUserById(int id)
{
return _context.Users.FirstOrDefault(u => u.Id == id);
}
public User GetUserByName(string name)
{
return _context.Users.FirstOrDefault(u=>u.Name==name);
}
public IEnumerable<User> GetAllUsers()
{
return _context.Users.ToList();
}
public User Login(string name, string pwd)
{
return _context.Users.FirstOrDefault(u=>u.Name==name && u.Pwd==pwd);
}
}
}
三.Services层
using CRUD3.Commons;
using CRUD3.Models;
namespace CRUD3.Services
{
public interface IUserservice
{
R<string> AddUser(User user);
R<string> DeleteUser(int id);
R<string> UpdateUser(User user);
R<User> GetUserById(int id);
R<User> GetUserByName(string name);
R<IEnumerable<User>> GetAllUsers();
R<User> Login(string name, string pwd);
string GenerateToken(string name);
void ClearToken(string? username);
}
}
using CRUD3.Commons;
using CRUD3.Models;
using Microsoft.IdentityModel.Tokens;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
namespace CRUD3.Services
{
public class UserService : IUserservice
{
private readonly IUserRespository _userRespository;
private readonly RSA _privateKey;
private readonly IDictionary<string, string> _userTokens;
public UserService(IUserRespository userRespository,RSA privateKey)
{
_userRespository = userRespository;
_privateKey = privateKey;
_userTokens= new Dictionary<string, string>();
}
public R<string> AddUser(User user)
{
var user1= _userRespository.GetUserByName(user.Name);
if(user1 != null)
{
return R<string>.Error("用户已存在");
}
else
{
_userRespository.AddUser(user);
return R<string>.Success("添加成功");
}
}
public R<string> DeleteUser(int id)
{
var user = _userRespository.GetUserById(id);
if(user == null)
{
return R<string>.Error("用户不存在,删除失败");
}
else
{
_userRespository.DeleteUser(id);
return R<string>.Success("删除成功");
}
}
public R<string> UpdateUser(User user)
{
var user1 = _userRespository.GetUserById(user.Id);
if (user1 == null)
{
return R<string>.Error("用户不存在,更新失败");
}
_userRespository.UpdateUser(user);
return R<string>.Success("更新成功");
}
public R<User> GetUserById(int id)
{
var user = _userRespository.GetUserById(id);
if (user == null)
{
throw new Exception("不存在此id的用户");
}
else
{
return R<User>.Success(user);
}
}
public R<User> GetUserByName(string name)
{
return R<User>.Success(_userRespository.GetUserByName (name));
}
public R<IEnumerable<User>> GetAllUsers()
{
return R < IEnumerable < User >> .Success(_userRespository.GetAllUsers());
}
public R<User> Login(string name, string pwd)
{
// 验证用户信息
return R < User > .Success(_userRespository.Login(name, pwd));
}
public string GenerateToken(string username)
{
var signingCredentials = new SigningCredentials(new RsaSecurityKey(_privateKey), SecurityAlgorithms.RsaSha256);
var claims = new[]
{
new Claim(ClaimTypes.Name, username)
};
var jwt = new JwtSecurityToken(
claims: claims,
signingCredentials: signingCredentials,
expires: DateTime.UtcNow.AddHours(1)); // 设置过期时间为 1 小时
var token = new JwtSecurityTokenHandler().WriteToken(jwt);
return token;
}
public void ClearToken(string username)
{
// 清除用户令牌字典中的令牌信息
if (_userTokens.ContainsKey(username))
{
_userTokens.Remove(username);
}
}
}
}
四.控制器
using CRUD3.Models;
using CRUD3.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
namespace CRUD3.Controllers
{
[Route("api/user")]
[ApiController]
public class UserController : Controller
{
private readonly IUserservice _userService;
public UserController(IUserservice userservice)
{
_userService = userservice;
}
// Get:api/user/1
[HttpGet("{id}")]
public IActionResult GetUserById(int id)
{
return Ok(_userService.GetUserById(id));
}
// Post:api/user
[HttpPost("add")]
public IActionResult AddUser(User user)
{
return Ok(_userService.AddUser(user));
}
// Delete:api/user/delete/1
[HttpDelete("delete/{id}")]
public IActionResult DeleteUser(int id)
{
return Ok(_userService.DeleteUser(id));
}
// Post:api/user/update
[HttpPost("update")]
public IActionResult UpdateUser(User user)
{
return Ok(_userService.UpdateUser(user));
}
// Get:api/user
[Authorize(Policy = "admin")]
[HttpGet]
public IActionResult GetAllUsers()
{
return Ok(_userService.GetAllUsers());
}
// Post:api/user/login
[HttpPost("login")]
public IActionResult Login(User user)
{
// 验证用户信息
var user1 = _userService.Login(user.Name, user.Pwd);
if (user1 != null)
{
// 生成令牌
var token = _userService.GenerateToken(user.Name);
return Ok(new { token });
}
else
{
return Unauthorized();
}
}
[HttpPost("logout")]
[Authorize]
public IActionResult Logout()
{
var username = User.Identity.Name;
_userService.ClearToken(username);
return Ok("logout successful");
}
//GET: api/user/index
[HttpGet("index")]
public IActionResult Index()
{
return Ok("welcome crud");
}
}
}