![]() |
VOOZH | about |
dotnet add package BugFree.Login --version 1.2.2026.616-beta0932
NuGet\Install-Package BugFree.Login -Version 1.2.2026.616-beta0932
<PackageReference Include="BugFree.Login" Version="1.2.2026.616-beta0932" />
<PackageVersion Include="BugFree.Login" Version="1.2.2026.616-beta0932" />Directory.Packages.props
<PackageReference Include="BugFree.Login" />Project file
paket add BugFree.Login --version 1.2.2026.616-beta0932
#r "nuget: BugFree.Login, 1.2.2026.616-beta0932"
#:package BugFree.Login@1.2.2026.616-beta0932
#addin nuget:?package=BugFree.Login&version=1.2.2026.616-beta0932&prereleaseInstall as a Cake Addin
#tool nuget:?package=BugFree.Login&version=1.2.2026.616-beta0932&prereleaseInstall as a Cake Tool
统一登录认证中心核心组件,为 .NET 应用提供开箱即用的本地认证能力。
| 认证方式 | 说明 |
|---|---|
| 账号密码登录 | 用户名/手机号/邮箱 + 密码,BCrypt 哈希验证 |
| 短信验证码登录 | 手机号 + 6 位短信验证码,SHA256 摘要存储 |
| 邮箱验证码登录 | 邮箱 + 6 位邮箱验证码 |
| 邮件魔法链接 | 邮箱 + 一次性魔法链接,无密码登录 |
IChallengeSender 后,创建挑战码时自动发送AuthErrorCodes),不泄露敏感信息dotnet add package BugFree.Login
using BugFree.Login.Extensions;
builder.Services.AddBugFreeLogin(jwt =>
{
jwt.Secret = "your-256-bit-secret-key-at-least-32-chars!";
jwt.Issuer = "MyApp";
jwt.Audience = "MyApp";
});
调用方需要实现以下接口,否则核心库无法运行:
IUserStore(必须)用户查找、密码哈希读取、状态检查。
public class MyUserStore : IUserStore
{
public async Task<UserInfo?> FindByAccountAsync(string account, CancellationToken ct)
{
// 按账号/手机号/邮箱查找用户
}
public async Task<string?> GetPasswordHashAsync(long userId, CancellationToken ct)
{
// 返回 BCrypt 哈希,无密码返回 null
}
public async Task<UserStatus> GetStatusAsync(long userId, CancellationToken ct)
{
// Active / Disabled / Locked
}
}
ITokenStore(必须)RefreshToken 生命周期管理(原文不存,只存 SHA256 摘要)。
public class MyTokenStore : ITokenStore
{
public async Task SaveAsync(TokenEntry entry, CancellationToken ct) { }
public async Task<TokenEntry?> GetAsync(string refreshTokenHash, CancellationToken ct) => null;
public async Task<bool> RevokeAsync(string refreshTokenHash, CancellationToken ct) => false;
public async Task<int> RevokeAllForUserAsync(long userId, CancellationToken ct) => 0;
}
IChallengeStore(必须)验证码/魔法链接的临时存储(一次性消费,原子操作)。
public class MyChallengeStore : IChallengeStore
{
public async Task SaveAsync(ChallengeEntry entry, CancellationToken ct) { }
public async Task<ChallengeEntry?> GetAsync(string challengeId, CancellationToken ct) => null;
public async Task<bool> ConsumeAsync(string challengeId, CancellationToken ct) => false;
}
IChallengeSender(可选)注册后,ChallengeService.CreateChallengeAsync 会自动调用发送验证码/链接。未注册则返回 rawCode 由调用方自行处理。
public class MyChallengeSender : IChallengeSender
{
readonly ISmsService _sms;
readonly IEmailService _email;
readonly string _baseUrl;
public async Task SendAsync(AuthProviderType type, string target, string challengeId, string code, CancellationToken ct)
{
switch (type)
{
case AuthProviderType.SmsCode:
await _sms.SendAsync(target, $"您的登录验证码是:{code}", ct);
break;
case AuthProviderType.EmailCode:
await _email.SendAsync(target, "登录验证码", $"您的验证码是:{code}", ct);
break;
case AuthProviderType.EmailLink:
var link = $"{_baseUrl}/auth/magic-link?c={challengeId}&t={code}";
await _email.SendAsync(target, "登录链接", $"点击链接登录:{link}", ct);
break;
}
}
}
// 必须实现
builder.Services.AddSingleton<IUserStore, MyUserStore>();
builder.Services.AddSingleton<ITokenStore, MyTokenStore>();
builder.Services.AddSingleton<IChallengeStore, MyChallengeStore>();
// 可选(自动发送验证码)
builder.Services.AddScoped<IChallengeSender, MyChallengeSender>();
// 核心服务(一行注册完成)
builder.Services.AddBugFreeLogin(jwt =>
{
jwt.Secret = "your-256-bit-secret-key-at-least-32-chars!";
jwt.Issuer = "MyApp";
jwt.Audience = "MyApp";
});
var result = await authManager.AuthenticateAsync(new LoginRequest
{
Account = "user@example.com",
Credential = "password123",
ProviderType = AuthProviderType.Password,
}, new AuthContext { IP = "127.0.0.1", DeviceId = "web-1" });
if (result.Success)
{
var accessToken = result.TokenPair!.AccessToken;
var refreshToken = result.TokenPair.RefreshToken;
}
// 注册了 IChallengeSender 后,自动发送
var (challengeId, _) = await challengeService.CreateChallengeAsync(
AuthProviderType.SmsCode, "13800138000");
// 短信已自动发出 ✓
// 用户提交验证码登录
var result = await authManager.AuthenticateAsync(new LoginRequest
{
Account = "13800138000",
Credential = userInputCode,
ProviderType = AuthProviderType.SmsCode,
ChallengeId = challengeId,
}, context);
BugFree.Login/
├── Abstractions/ 契约层(按功能域划分)
│ ├── Auth/ 认证模型 + IAuthProvider
│ ├── Token/ Token 模型 + IJwtService + ITokenStore
│ ├── Challenge/ ChallengeEntry + IChallengeService + IChallengeStore + IChallengeSender
│ └── User/ UserInfo + UserStatus + IUserStore
├── Errors/ AuthErrorCodes 稳定错误码
├── Extensions/ AddBugFreeLogin() DI 注册
├── Providers/ AuthManager + PasswordAuthProvider + ChallengeAuthProvider
└── Services/ ChallengeService + DefaultJwtService(实现)
BugFree.Login.Tests/ 41 个单元测试(xUnit + Moq)
BugFree.Security PasswordHashService BCrypt 哈希(WorkFactor)BugFree.Core SecureRandomStringGenerator 生成dotnet test
覆盖场景:
MIT
dotnet test
覆盖场景:
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.2.2026.616-beta0932 | 42 | 6/16/2026 |
| 1.2.2026.615-beta1139 | 43 | 6/15/2026 |
| 1.2.2026.614-beta1731 | 43 | 6/14/2026 |