Two-Factor Authentication (2FA)¶
Knosc supports TOTP-based two-factor authentication (compatible with Google Authenticator, Authy, 1Password, etc.).
Setup: Generate Secret¶
Authentication required.
CSRF header required: X-XSRF-TOKEN
Generates a new 2FA secret and returns a QR code for scanning with an authenticator app.
Response¶
| Field | Type | Description |
|---|---|---|
secret |
string | Base32-encoded TOTP secret for manual entry |
qr_code |
string | Base64-encoded QR code image (data URI) |
Setup: Activate 2FA¶
Authentication required.
CSRF header required: X-XSRF-TOKEN
Confirms that the user has successfully scanned the QR code by verifying the first TOTP code. 2FA is only enabled after this call succeeds.
Request Body¶
| Field | Type | Required | Description |
|---|---|---|---|
totp_code |
string | Yes | 6-digit TOTP code from the authenticator app |
Response - Success¶
Response - Invalid Code¶
Login: Verify 2FA Code¶
Public endpoint. Called after a login attempt that returns {"requires_2fa": true}.
Request Body¶
| Field | Type | Required | Description |
|---|---|---|---|
username |
string | Yes | The username used in the initial login attempt |
totp_code |
string | Yes | Current 6-digit TOTP code |
Response - Success¶
HTTP/1.1 200 OK
Set-Cookie: access_token_cookie=<jwt>; HttpOnly; SameSite=Lax; Path=/
Set-Cookie: csrf_access_token=<token>; SameSite=Lax; Path=/
{
"login": true
}
Response - Invalid Code¶
Admin: Reset User 2FA¶
Required role: Administrator
CSRF header required: X-XSRF-TOKEN
Disables 2FA for the specified user. The user will be prompted to set up 2FA again on next login if 2FA is required by policy.
Path Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id |
integer | Yes | Internal user identifier |
Response¶
2FA Login Flow¶
1. POST /api/authenticate → {"requires_2fa": true}
2. User opens authenticator app
3. POST /api/verify-2fa → {"login": true} + session cookies
4. Normal API usage begins
Code Example¶
import requests
BASE = "https://acme.knosc.com"
session = requests.Session()
# Step 1 - Initial login
r = session.post(f"{BASE}/api/authenticate", json={
"username": "jane.doe@acme.com",
"password": "your-password"
})
body = r.json()
if body.get("requires_2fa"):
# Step 2 - Provide TOTP code
totp_code = input("Enter 2FA code: ")
r = session.post(f"{BASE}/api/verify-2fa", json={
"username": "jane.doe@acme.com",
"totp_code": totp_code
})
assert r.json().get("login"), "2FA verification failed"
elif body.get("login"):
pass # No 2FA, already logged in