@solidus-network/auth
DID tabanlı kimlik doğrulama için kimlik doğrulama ilkelleri. Bu paket, bir doğrulayıcının bir nonce yayınladığı, sahibin bunu doğrulanabilir bir sunum olarak imzaladığı ve doğrulayıcının imzayı kontrol ettiği bir meydan okuma-yanıt protokolü uygular.
npm install @solidus-network/authimport { createChallenge, verifyPresentation } from '@solidus-network/auth'createChallenge
Bir DID sahibinin özel anahtarının kontrolünü kanıtlaması için kriptografik bir meydan okuma üretir.
createChallenge(did: string, ttlSeconds?: number): ChallengeParametreler
| Ad | Tür | Varsayılan | Açıklama |
|---|---|---|---|
did | string | — | Meydan okunacak DID |
ttlSeconds | number | 300 | Saniye cinsinden yaşam süresi (varsayılan 5 dakika) |
Bir Challenge nesnesi döndürür.
interface Challenge {
id: string // UUID v4
did: string // The challenged DID
nonce: string // 32-byte random hex nonce
issuedAt: string // ISO 8601 timestamp
expiresAt: string // ISO 8601 timestamp (issuedAt + ttlSeconds)
}Nasıl çalışır:
- Meydan okuma kimliği olarak bir UUID v4 üretir
- Nonce olarak hex kodlanmış, 32 bayt kriptografik olarak rastgele veri üretir
issuedAt’i şu anki zamana ayarlarexpiresAt’iissuedAt + ttlSecondsolarak ayarlar (varsayılan 300 saniye)
Örnek
import { createChallenge } from '@solidus-network/auth'
// Default 5-minute TTL
const challenge = createChallenge('did:solidus:testnet:user123')
console.log(challenge)
// {
// id: "f47ac10b-58cc-4372-a567-0e02b2c3d479",
// did: "did:solidus:testnet:user123",
// nonce: "a4f2e8c1d3b5f6a7890123456789abcdef...",
// issuedAt: "2026-05-07T12:00:00.000Z",
// expiresAt: "2026-05-07T12:05:00.000Z"
// }
// Custom 60-second TTL
const shortChallenge = createChallenge(
'did:solidus:testnet:user123',
60
)verifyPresentation
İmzalanmış bir doğrulanabilir sunumu bir meydan okumaya karşı doğrular. Dört adımlı sıralı kontrol gerçekleştirir — herhangi bir kontrol başarısız olursa, doğrulama durur ve başarısızlık nedenini döndürür.
verifyPresentation(
challenge: Challenge,
presentation: VerifiablePresentation,
getPublicKey: (did: string) => Promise<Uint8Array>
): Promise<PresentationVerificationResult>Parametreler
| Ad | Tür | Açıklama |
|---|---|---|
challenge | Challenge | Orijinal meydan okuma nesnesi |
presentation | VerifiablePresentation | Sahipten gelen imzalanmış sunum |
getPublicKey | (did: string) => Promise<Uint8Array> | Bir DID’i Ed25519 açık anahtarına çözümlemek için geri çağırma (callback) |
Bir PresentationVerificationResult döndürür.
interface PresentationVerificationResult {
valid: boolean
did?: string
error?: string
}Doğrulama Adımları
Dört kontrol sırayla çalışır. Herhangi biri başarısız olursa, kalan kontroller atlanır.
| Adım | Kontrol | Şu durumda başarısız olur |
|---|---|---|
| 1 | Son kullanma | Date.now() > challenge.expiresAt |
| 2 | Sahip eşleşmesi | presentation.holder !== challenge.did |
| 3 | Nonce eşleşmesi | presentation.proof.challenge !== challenge.nonce |
| 4 | İmza | Ed25519 imza doğrulaması başarısız olur |
Sunum Biçimi
Sahip, bu biçimde bir VerifiablePresentation oluşturmalıdır:
interface VerifiablePresentation {
'@context': ['https://www.w3.org/2018/credentials/v1']
type: ['VerifiablePresentation']
holder: string // The holder's DID
proof: {
type: 'Ed25519Signature2020'
created: string // ISO 8601 timestamp
verificationMethod: string // DID key reference (e.g. "did:solidus:...#key-1")
proofPurpose: 'authentication'
challenge: string // The nonce from the challenge
jws: string // Detached JWS signature
}
}JWS Biçimi
jws alanı, ayrık (detached) JWS biçimini kullanır: base64url(header)..base64url(signature) (iki noktaya dikkat edin — yük (payload) atlanmıştır).
Başlık şudur:
{ "alg": "EdDSA", "b64": false, "crit": ["b64"] }İmza, sahibin Ed25519 özel anahtarı kullanılarak meydan okuma nonce’u üzerinden hesaplanır.
Eksiksiz Kimlik Doğrulama Akışı
Meydan okuma oluşturmayı, sunum imzalamayı ve doğrulamayı gösteren tam bir örnek aşağıdadır.
import { createChallenge, verifyPresentation } from '@solidus-network/auth'
import { ed25519 } from '@noble/ed25519'
// --- Verifier side ---
// 1. Create a challenge
const challenge = createChallenge('did:solidus:testnet:user123')
// Send challenge.id and challenge.nonce to the holder...
// --- Holder side ---
// 2. Build and sign a presentation
const presentation = {
'@context': ['https://www.w3.org/2018/credentials/v1'],
type: ['VerifiablePresentation'],
holder: 'did:solidus:testnet:user123',
proof: {
type: 'Ed25519Signature2020',
created: new Date().toISOString(),
verificationMethod: 'did:solidus:testnet:user123#key-1',
proofPurpose: 'authentication',
challenge: challenge.nonce,
jws: await signDetachedJws(challenge.nonce, privateKey),
},
}
// Send presentation back to verifier...
// --- Verifier side ---
// 3. Verify the presentation
const result = await verifyPresentation(
challenge,
presentation,
async (did) => {
// Resolve the DID to get its public key
const doc = await resolveDid(did)
return doc.verificationMethod[0].publicKeyBytes
}
)
if (result.valid) {
console.log('Authenticated:', result.did)
// Create session, issue JWT, etc.
} else {
console.log('Authentication failed:', result.error)
}Hata Durumları
| Hata | Neden | Çözüm |
|---|---|---|
"Challenge expired" | 300 saniyeden (veya özel TTL’den) fazla süre geçti | Yeni bir meydan okuma yayınlayın |
"Holder mismatch" | Sunum sahibi DID’i, meydan okunan DID ile eşleşmiyor | Doğru DID’in imzaladığından emin olun |
"Nonce mismatch" | Kanıt meydan okuma alanı, yayınlanan nonce ile eşleşmiyor | Orijinal meydan okumadaki nonce’u kullanın |
"Invalid signature" | Ed25519 imzası doğrulanmıyor | Anahtar çiftini ve imzalama mantığını kontrol edin |