IGeekFan.AspNetCore.Identity.FreeSql
ASP.NET Core Identity 的 FreeSql 存储实现。
功能概览
| 功能 | 说明 |
|---|---|
| Identity 存储 | ASP.NET Core Identity FreeSql 实现 |
| 多数据库 | 支持 MySQL、PostgreSQL、SQLite 等 |
安装
dotnet add package IGeekFan.AspNetCore.Identity.FreeSql
dotnet add package FreeSql.Provider.MySqlConnector # 或其他 Provider
快速开始
场景:用户注册登录
1. 定义用户和角色
public class AppUser : IdentityUser<Guid>
{
public string FirstName { get; set; } = default!;
public string LastName { get; set; } = default!;
}
public class AppRole : IdentityRole<Guid>
{
}
2. 创建 DbContext
public class AppIdentityDbContext : IdentityDbContext<AppUser, AppRole, Guid>
{
public AppIdentityDbContext(
IOptions<IdentityOptions> identityOptions,
IFreeSql fsql,
DbContextOptions options)
: base(identityOptions.Value, fsql, options)
{
}
protected override void OnModelCreating(ICodeFirst codefirst)
{
base.OnModelCreating(codefirst);
codefirst.ApplyConfiguration(new AppUserConfiguration());
}
}
3. Fluent API 配置
public class AppUserConfiguration : IEntityTypeConfiguration<AppUser>
{
public void Configure(EfCoreTableFluent<AppUser> builder)
{
builder.Property(x => x.FirstName).HasMaxLength(50);
builder.Property(x => x.LastName).HasMaxLength(50);
}
}
4. 注册服务
// 扩展方法
public static IServiceCollection AddFreeSqlIdentity(
this IServiceCollection services, IConfiguration configuration)
{
// 注册 FreeSql
services.AddSingleton<IFreeSql>(sp =>
{
var fsql = new FreeSqlBuilder()
.UseConnectionString(DataType.MySql, configuration["ConnectionStrings:MySql"])
.UseAutoSyncStructure(true)
.Build();
fsql.GlobalFilter.Apply<ISoftDelete>("IsDeleted", a => a.IsDeleted == false);
return fsql;
});
services.AddFreeRepository();
services.AddScoped<UnitOfWorkManager>();
// 注册 DbContext
services.AddFreeDbContext<AppIdentityDbContext>(options => options
.UseOptions(new DbContextOptions { EnableCascadeSave = true }));
// 配置 Identity
services.AddAuthentication(o =>
{
o.DefaultScheme = IdentityConstants.ApplicationScheme;
o.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
.AddIdentityCookies(o => { });
services.AddIdentityCore<AppUser>(o =>
{
o.SignIn.RequireConfirmedEmail = false;
o.Stores.MaxLengthForKeys = 128;
})
.AddRoles<AppRole>()
.AddSignInManager()
.AddFreeSqlStores<AppIdentityDbContext>()
.AddDefaultTokenProviders();
return services;
}
5. Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddFreeSqlIdentity(builder.Configuration);
var app = builder.Build();
// 同步表结构
using (var scope = app.Services.CreateScope())
{
var fsql = scope.ServiceProvider.GetRequiredService<IFreeSql>();
fsql.CodeFirst.SyncStructure(typeof(AppUser), typeof(AppRole));
}
app.Run();
API 示例
注册用户
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly UserManager<AppUser> _userManager;
public AuthController(UserManager<AppUser> userManager) => _userManager = userManager;
[HttpPost("register")]
public async Task<IActionResult> Register(RegisterRequest request)
{
var user = new AppUser
{
FirstName = request.FirstName,
LastName = request.LastName,
EmailConfirmed = true
};
await _userManager.SetUserNameAsync(user, request.Email, CancellationToken.None);
await ((IUserEmailStore<AppUser>)_userManager).SetEmailAsync(user, request.Email, CancellationToken.None);
var result = await _userManager.CreateAsync(user, request.Password);
return result.Succeeded ? Ok() : BadRequest(result.Errors);
}
}
public record RegisterRequest(string FirstName, string LastName, string Email, string Password);
登录
[HttpPost("login")]
public async Task<IActionResult> Login(LoginRequest request)
{
var result = await _signInManager.PasswordSignInAsync(
request.Email, request.Password, request.RememberMe, false);
if (result.Succeeded)
{
var user = await _userManager.FindByEmailAsync(request.Email);
var token = Guid.NewGuid().ToString(); // 生成 Token
return Ok(token);
}
return Unauthorized();
}
public record LoginRequest(string Email, string Password, bool RememberMe);
数据库配置
{
"ConnectionStrings": {
"MySql": "Data Source=localhost;Port=3306;User ID=root;Password=root;Initial Catalog=mydb;Charset=utf8mb4"
}
}
故障排查
| 问题 | 解决方案 |
|---|---|
| 表未创建 | 确保调用 CodeFirst.SyncStructure |
| 密码验证失败 | 检查 IdentityOptions 配置 |
| 登录失败 | 检查用户是否存在、密码是否正确 |