Nedo.AspNet.Authentication.Totp
2.0.9
dotnet add package Nedo.AspNet.Authentication.Totp --version 2.0.9
NuGet\Install-Package Nedo.AspNet.Authentication.Totp -Version 2.0.9
<PackageReference Include="Nedo.AspNet.Authentication.Totp" Version="2.0.9" />
<PackageVersion Include="Nedo.AspNet.Authentication.Totp" Version="2.0.9" />
<PackageReference Include="Nedo.AspNet.Authentication.Totp" />
paket add Nedo.AspNet.Authentication.Totp --version 2.0.9
#r "nuget: Nedo.AspNet.Authentication.Totp, 2.0.9"
#:package Nedo.AspNet.Authentication.Totp@2.0.9
#addin nuget:?package=Nedo.AspNet.Authentication.Totp&version=2.0.9
#tool nuget:?package=Nedo.AspNet.Authentication.Totp&version=2.0.9
Nedo.AspNet.Authentication.Totp
TOTP (RFC 6238) two-factor authentication for Nedo.AspNet.Authentication.Local. Registering this package activates the MFA branch in every sign-in path (password, social, magic-link, passkey) — LocalAuthService checks IMultiFactorChallenge after the credential step and returns RequiresMfa with a short-lived pendingAuthToken if the user has TOTP enrolled.
Install
dotnet add package Nedo.AspNet.Authentication.Totp
Quickstart
using Microsoft.EntityFrameworkCore;
using Nedo.AspNet.Authentication.Totp;
builder.Services.AddTotp(
db => db.UseNpgsql(builder.Configuration.GetConnectionString("Postgres")!), // share the same DB as Local
opts => opts.Issuer = "My App"); // shown in the authenticator app
// In the pipeline:
app.MapLocalAuth();
app.MapTotpAuth(); // /auth/2fa/{setup,enable,verify,disable,status}
That's it — TotpService implements IMultiFactorChallenge, so login/social/magic-link/passkey automatically gate on it for users who have enabled 2FA.
Endpoints
| Method | Path | Auth | Body | Returns |
|---|---|---|---|---|
| POST | /auth/2fa/setup |
bearer | — | { secret, otpauthUri, issuer, accountName } |
| POST | /auth/2fa/enable |
bearer | { code } |
{ recoveryCodes: string[] } |
| POST | /auth/2fa/verify |
anon | { pendingAuthToken, code } |
TokenResponse |
| POST | /auth/2fa/disable |
bearer | — | { message } |
| GET | /auth/2fa/status |
bearer | — | { enabled, remainingCodes } |
Sign-in flow with 2FA
client API
│
├──── POST /auth/login ───────►│
│ │ password ✓ → MFA required
│◄─── { requiresMfa: true, ───┤
│ pendingAuthToken } │
│
│ user types 6-digit code
│
├──── POST /auth/2fa/verify ──►│
│ { pendingAuthToken, │ verify TOTP / recovery code
│ code } │
│◄─── TokenResponse ───────────┤
│ { accessToken, ... } │
The same flow applies to social / magic-link / passkey assertion — every path that returns RequiresMfa is redeemed via the same /auth/2fa/verify endpoint.
Recovery codes
enable returns a one-time list of recovery codes (8 by default, single-use each). Treat them like passwords. The user can spend one in /auth/2fa/verify instead of a TOTP code if they lose their authenticator.
Storage
Two tables provisioned alongside the Local schema:
| Table | Purpose |
|---|---|
nedo_totp_enrollments |
Per-user secret + enabled flag. |
nedo_totp_recovery_codes |
SHA-256 hashed recovery codes; consumed on use. |
Customizable via TotpSchemaOptions passed to AddTotp.
Docs
docs/providers/totp.md — full walkthrough including the React enrollment UI pattern (QR + manual-entry secret).
Related
| Package | Role |
|---|---|
Nedo.AspNet.Authentication.Local |
Required peer — provides IMultiFactorChallenge consumer + the redeem flow. |
License
MIT — see LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- Microsoft.EntityFrameworkCore.Relational (>= 9.0.0)
- Nedo.AspNet.Authentication (>= 2.0.9)
- Nedo.AspNet.Authentication.Local (>= 2.0.9)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.