Autentificare cu Dazr Identity: documentație pentru dezvoltatori
OpenID Connect 1.0 standard, cu fluxul authorization code și PKCE. Nu este nevoie de SDK: funcționează orice bibliotecă OpenID Connect certificată, la fel și codul simplu.
Oamenii își pot folosi deja contul Google sau Microsoft în cadrul Dazr Identity, așa că aplicația dumneavoastră nu are nevoie de butoane Google și Microsoft separate alături: un singur buton în loc de trei.
Descoperire și endpointuri
Totul este descris în documentul de descoperire. Îndreptați biblioteca spre emitent și găsește singură restul.
| Ce | Adresă |
|---|---|
| Emitent | https://identity.dazr.eu |
| Discovery | https://identity.dazr.eu/.well-known/openid-configuration |
| Autorizare | https://identity.dazr.eu/oauth/authorize |
| Token | https://identity.dazr.eu/oauth/token |
| Informații despre utilizator | https://identity.dazr.eu/oauth/userinfo |
| Chei publice (JWKS) | https://identity.dazr.eu/oauth/jwks |
| Revocare (RFC 7009) | https://identity.dazr.eu/oauth/revoke |
| Introspecție (RFC 7662), doar aplicații cu server web | https://identity.dazr.eu/oauth/introspect |
| Deconectare (inițiată de RP) | https://identity.dazr.eu/oauth/logout |
| Rapoarte de verificare, doar aplicații cu server web | https://identity.dazr.eu/oauth/verification-report |
Înregistrați o aplicație
- Aplicațiile aparțin unei organizații. Proprietarii și administratorii organizației le înregistrează în Dezvoltatori.
- Aplicațiile cu server web (clienți confidențiali) primesc un secret de client, afișat o singură dată. Autentificați-vă la endpointul de token cu HTTP Basic (
client_secret_basic) sau în corpul formularului (client_secret_post). - Aplicațiile single-page și mobile (clienți publici) nu primesc secret. Trimit
client_idși se bazează pe PKCE. - URI-urile de redirecționare trebuie să corespundă exact. Trebuie să fie
https://. Cât timp aplicația este în testare, funcționează șihttp://localhostșihttp://127.0.0.1, pe orice port. - Sunt obligatorii adresa politicii de confidențialitate, o adresă de e-mail de asistență și o descriere a scopului într-un rând: oamenii le văd pe ecranul de consimțământ.

Ghiduri de integrare
Fiecare tehnologie de mai jos își folosește propriul suport OpenID Connect standard. Aveți nevoie de trei valori din consolă: ID-ul clientului, secretul clientului (doar aplicații cu server web) și URI-ul de redirecționare înregistrat. Restul vine din documentul de descoperire.
- Auth.js / NextAuth
- Next.js App Router
- WordPress
- Laravel
- Supabase
- Django
- Node.js (openid-client)
- Orice bibliotecă OpenID Connect
sub este pereche: același pentru fiecare aplicație a organizației dumneavoastră, diferit pentru orice altă organizație. Nu se schimbă niciodată pentru o persoană, în timp ce o adresă de e-mail se poate schimba. Stocați sub drept cheie a contului și tratați email ca dată de contact.
Auth.js / NextAuth
Auth.js (NextAuth.js v5) acceptă un obiect de furnizor OpenID Connect personalizat. Înregistrați o aplicație cu server web, setați AUTH_SECRET, AUTH_DAZR_ID și AUTH_DAZR_SECRET și folosiți acest URL de callback ca URI de redirecționare: https://app.example.eu/api/auth/callback/dazr.
// auth.ts
import NextAuth from "next-auth"
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [
{
id: "dazr",
name: "Dazr Identity",
type: "oidc",
issuer: "https://identity.dazr.eu",
clientId: process.env.AUTH_DAZR_ID,
clientSecret: process.env.AUTH_DAZR_SECRET,
authorization: { params: { scope: "openid profile email" } },
checks: ["pkce", "state", "nonce"],
client: { id_token_signed_response_alg: "ES256" },
},
],
})
NextAuth.js v4 folosește aceeași idee cu type: "oauth" și URL-ul de descoperire:
// pages/api/auth/[...nextauth].ts (NextAuth.js v4), in providers: [ ... ]
{
id: "dazr",
name: "Dazr Identity",
type: "oauth",
wellKnown: "https://identity.dazr.eu/.well-known/openid-configuration",
clientId: process.env.DAZR_CLIENT_ID,
clientSecret: process.env.DAZR_CLIENT_SECRET,
authorization: { params: { scope: "openid profile email" } },
idToken: true,
checks: ["pkce", "state"],
client: { id_token_signed_response_alg: "ES256" },
profile(profile) {
return { id: profile.sub, name: profile.name ?? null, email: profile.email }
},
}
Next.js App Router
Cu fișierul auth.ts de mai sus, adăugați handlerul de rută și un buton de autentificare care rulează o acțiune pe server.
// app/api/auth/[...nextauth]/route.ts
import { handlers } from "@/auth"
export const { GET, POST } = handlers
// app/page.tsx
import { auth, signIn, signOut } from "@/auth"
export default async function Page() {
const session = await auth()
if (session?.user) {
return (
<form action={async () => { "use server"; await signOut() }}>
<p>Signed in as {session.user.email}</p>
<button type="submit">Sign out</button>
</form>
)
}
return (
<form action={async () => { "use server"; await signIn("dazr") }}>
<button type="submit" className="dazr-signin">Sign in with Dazr Identity</button>
</form>
)
}
Stilizați butonul așa cum se arată la Butonul. În callbackuri, sub-ul Dazr este account.providerAccountId.
WordPress
Folosiți un plugin generic de client OpenID Connect, cum ar fi OpenID Connect Generic Client. Înregistrați o aplicație cu server web și completați setările pluginului cu valorile de mai jos. Pluginul afișează pe pagina de setări URI-ul de redirecționare de înregistrat; implicit este https://example.com/wp-admin/admin-ajax.php?action=openid-connect-authorize.
| Setare | Valoare |
|---|---|
| ID-ul clientului | ID-ul dumneavoastră de client |
| Secretul clientului | secretul dumneavoastră de client |
| Scope | openid profile email |
| Endpoint de conectare (autorizare) | https://identity.dazr.eu/oauth/authorize |
| Endpoint de token | https://identity.dazr.eu/oauth/token |
| Endpoint de informații despre utilizator | https://identity.dazr.eu/oauth/userinfo |
| Endpoint de încheiere a sesiunii | https://identity.dazr.eu/oauth/logout |
| Cheie de identitate | sub |
| PKCE | activat (S256) |
Denumirile setărilor diferă puțin de la un plugin la altul. Dacă un plugin nu are opțiunea PKCE, alegeți altul: Dazr Identity respinge autentificările fără PKCE.
Laravel
Laravel Socialite nu are un driver generic OpenID Connect integrat, așa că adăugați un mic driver personalizat. Acesta trimite oamenii la Dazr cu PKCE și citește utilizatorul de la endpointul de informații despre utilizator. Socialite nu citește documentul de descoperire, așa că endpointurile sunt scrise explicit. Înregistrați o aplicație cu server web cu URI-ul de redirecționare https://app.example.eu/auth/dazr/callback.
<?php
// app/Socialite/DazrProvider.php
namespace App\Socialite;
use Laravel\Socialite\Two\AbstractProvider;
use Laravel\Socialite\Two\User;
class DazrProvider extends AbstractProvider
{
protected $scopes = ['openid', 'profile', 'email'];
protected $scopeSeparator = ' ';
protected $usesPKCE = true;
protected function getAuthUrl($state)
{
return $this->buildAuthUrlFromBase('https://identity.dazr.eu/oauth/authorize', $state);
}
protected function getTokenUrl()
{
return 'https://identity.dazr.eu/oauth/token';
}
protected function getUserByToken($token)
{
$response = $this->getHttpClient()->get('https://identity.dazr.eu/oauth/userinfo', [
'headers' => ['Authorization' => 'Bearer '.$token],
]);
return json_decode((string) $response->getBody(), true);
}
protected function mapUserToObject(array $user)
{
return (new User)->setRaw($user)->map([
'id' => $user['sub'],
'name' => $user['name'] ?? null,
'email' => $user['email'] ?? null,
]);
}
}
// config/services.php
'dazr' => [
'client_id' => env('DAZR_CLIENT_ID'),
'client_secret' => env('DAZR_CLIENT_SECRET'),
'redirect' => env('DAZR_REDIRECT_URI'),
],
// app/Providers/AppServiceProvider.php, in boot()
use Laravel\Socialite\Facades\Socialite;
use App\Socialite\DazrProvider;
Socialite::extend('dazr', function ($app) {
return Socialite::buildProvider(DazrProvider::class, config('services.dazr'));
});
// routes/web.php
Route::get('/auth/dazr', fn () => Socialite::driver('dazr')->redirect());
Route::get('/auth/dazr/callback', function () {
$dazr = Socialite::driver('dazr')->user();
$user = \App\Models\User::updateOrCreate(
['dazr_sub' => $dazr->getId()],
['name' => $dazr->getName() ?? $dazr->getEmail(), 'email' => $dazr->getEmail()],
);
Auth::login($user);
return redirect('/');
});
Supabase
Supabase Auth nu are un furnizor generic OpenID Connect pe care să îl îndreptați spre orice emitent: furnizorii de autentificare și integrările de autentificare terțe sunt liste fixe. Așa că deocamdată nu puteți adăuga Dazr Identity în tabloul de bord Supabase. Dacă Supabase adaugă suport generic OpenID Connect, folosiți valorile din lista de verificare de mai jos.
Alternativa: autentificați oamenii cu Dazr Identity pe propriul server (cu unul dintre ghidurile de pe această pagină), stocați sub-ul Dazr în tabelul de utilizatori și comunicați cu Supabase de pe acel server cu cheia service role, verificând accesul în propriul cod. Nu trimiteți niciodată cheia service role într-un browser.
Django
Folosiți mozilla-django-oidc. Înregistrați o aplicație cu server web cu URI-ul de redirecționare https://app.example.eu/oidc/callback/. Biblioteca nu citește documentul de descoperire, așa că endpointurile sunt scrise explicit.
# settings.py
import os
INSTALLED_APPS += ["mozilla_django_oidc"] # after django.contrib.auth
AUTHENTICATION_BACKENDS = [
"mozilla_django_oidc.auth.OIDCAuthenticationBackend",
"django.contrib.auth.backends.ModelBackend",
]
OIDC_RP_CLIENT_ID = os.environ["DAZR_CLIENT_ID"]
OIDC_RP_CLIENT_SECRET = os.environ["DAZR_CLIENT_SECRET"]
OIDC_RP_SCOPES = "openid profile email"
OIDC_RP_SIGN_ALGO = "ES256"
OIDC_OP_JWKS_ENDPOINT = "https://identity.dazr.eu/oauth/jwks"
OIDC_OP_AUTHORIZATION_ENDPOINT = "https://identity.dazr.eu/oauth/authorize"
OIDC_OP_TOKEN_ENDPOINT = "https://identity.dazr.eu/oauth/token"
OIDC_OP_USER_ENDPOINT = "https://identity.dazr.eu/oauth/userinfo"
OIDC_USE_PKCE = True
OIDC_PKCE_CODE_CHALLENGE_METHOD = "S256"
LOGIN_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = "/"
# urls.py
from django.urls import include, path
urlpatterns += [path("oidc/", include("mozilla_django_oidc.urls"))]
# template: start the sign-in
# <a href="{% url 'oidc_authentication_init' %}">Sign in with Dazr Identity</a>
Implicit, backendul identifică utilizatorii după e-mail. Pentru a identifica conturile după sub, creați o subclasă a OIDCAuthenticationBackend și suprascrieți filter_users_by_claims și create_user. Folosiți o versiune actuală: versiunile mai vechi nu pot verifica semnăturile ES256.
Node.js (openid-client)
openid-client (versiunea 6) citește documentul de descoperire și verifică pentru dumneavoastră PKCE, state, nonce și tokenul ID.
import * as client from 'openid-client';
const config = await client.discovery(
new URL('https://identity.dazr.eu'),
process.env.DAZR_CLIENT_ID,
process.env.DAZR_CLIENT_SECRET, // public client: pass undefined here and client.None() as the 4th argument
);
const redirect_uri = 'https://app.example.eu/auth/dazr/callback';
// 1. Start: keep the three random values in the user's session.
export async function start(session) {
session.verifier = client.randomPKCECodeVerifier();
session.state = client.randomState();
session.nonce = client.randomNonce();
return client.buildAuthorizationUrl(config, {
redirect_uri,
scope: 'openid profile email',
code_challenge: await client.calculatePKCECodeChallenge(session.verifier),
code_challenge_method: 'S256',
state: session.state,
nonce: session.nonce,
});
}
// 2. Callback: pass the full callback URL (a URL object).
export async function callback(session, currentUrl) {
const tokens = await client.authorizationCodeGrant(config, currentUrl, {
pkceCodeVerifier: session.verifier,
expectedState: session.state,
expectedNonce: session.nonce,
});
const claims = tokens.claims(); // sub, email, name
return { sub: claims.sub, email: claims.email, name: claims.name };
}
Orice bibliotecă OpenID Connect
Dacă tehnologia dumneavoastră nu este listată, funcționează orice client OpenID Connect. Verificați aceste setări:
- Emitent
https://identity.dazr.eu, URL de descoperirehttps://identity.dazr.eu/.well-known/openid-configuration. - Tip de răspuns
code(fluxul authorization code). Fără flux implicit sau hibrid. - PKCE este obligatoriu, cu
code_challenge_method=S256. - Domenii de acces:
openidplus doar ce aveți nevoie dintreprofile,email,address,organisationsșioffline_access. Aplicația trebuie să fie înregistrată pentru fiecare domeniu pe care îl cere. - URI de redirecționare: exact cum este înregistrat în consolă, inclusiv calea și eventualul șir de interogare.
- Autentificarea clientului:
client_secret_basicsauclient_secret_postpentru aplicațiile cu server web,nonepentru aplicațiile single-page și mobile. - Semnătura tokenului ID: ES256. Unele biblioteci presupun RS256: setați algoritmul la ES256.
- Folosiți
subdrept cheie a contului. Este pereche, per organizație. - Cu
offline_access, stocați noul token de reîmprospătare după fiecare reîmprospătare: acestea se rotesc.
Fluxul
- Creați un
code_verifieraleatoriu (43-128 de caractere) șicode_challenge-ul său = base64url(SHA-256(verifier)). Creați unstateși unnoncealeatorii. Păstrați-le pe toate trei în sesiunea utilizatorului. - Redirecționați la endpointul de autorizare cu
response_type=code,client_id,redirect_uri,scope(incluzând întotdeaunaopenid),state,nonce,code_challengeșicode_challenge_method=S256. - Persoana se autentifică dacă este nevoie și vede ecranul de consimțământ cu datele reale. Când permite, revine la URI-ul de redirecționare cu
code,stateșiiss. Verificați căstatecorespunde și căissestehttps://identity.dazr.eu. - Pe server, trimiteți un POST la endpointul de token cu
grant_type=authorization_code,code, acelașiredirect_urișicode_verifier. - Verificați tokenul ID: semnătura ES256 cu o cheie din JWKS (potriviți
kid),iss,aud= ID-ul dumneavoastră de client,expșinonce-ul dumneavoastră. Folosițisubdrept cheie a contului.

Parametrul prompt acceptă none (răspunde imediat cu login_required sau consent_required dacă persoana ar trebui să acționeze), login (cere persoanei să se autentifice din nou) și consent (afișează ecranul de consimțământ chiar dacă a fost aprobat anterior). max_age este acceptat. Consimțământ reținut: dacă persoana a aprobat anterior aceleași domenii de acces, revine direct în aplicație. Dacă cereți mai mult ulterior, ecranul de consimțământ listează doar ce este nou.
Domenii de acces și claimuri
Cereți doar ce aveți nevoie. Nimic din afara acestui tabel nu există: fără contacte, fără fișiere, fără parole.
| Scope | Claimuri |
|---|---|
openid (obligatoriu) | sub: un ID aleatoriu pentru persoană, același pentru fiecare aplicație a organizației dumneavoastră și diferit pentru orice altă organizație |
profile | name (dacă este setat) și locale |
email | email și email_verified (întotdeauna true) |
address | address (formatted, street_address, locality, region, postal_code, country), doar dacă persoana a salvat una |
organisations | organisations: organizațiile pe care persoana le bifează pe ecranul de consimțământ, fiecare cu id, name, display_name, website, country, register_number, vat, vat_verified (true doar când serviciul VIES al UE a confirmat codul de TVA), verified, verification (vedeți Organizații verificate) și role (owner, admin sau member) |
offline_access | fără claimuri; primiți și un token de reîmprospătare |
Claimurile apar în tokenul ID pentru domeniile de acces aprobate de persoană. Endpointul de informații despre utilizator returnează același set, cu valorile curente.
Organizații verificate
Dazr verifică o organizație doar când surse oficiale dovedesc două lucruri: cine este persoana și că reprezintă această organizație, cu numele, numărul de înregistrare și codul de TVA ale acesteia. De obicei, administratorul semnează o scurtă declarație cu o semnătură electronică calificată (QES) și adaugă extrasul din registrul comerțului care îl menționează; cu un extras sigilat de registru, precum visura italiană sau un extras KvK neerlandez, este instantaneu, altfel Dazr îl analizează. O semnătură calificată singură nu face niciodată o organizație verificată. Fiecare organizație din claimul organisations poartă verificarea sa actuală:

| verification.status | Semnificație |
|---|---|
unverified | Neverificată sau o verificare a eșuat, a expirat ori a fost revocată (de exemplu după schimbarea denumirii legale sau a numărului de înregistrare). |
pending | Verificarea este în curs: reprezentantului i s-a cerut să semneze, extrasul din registrul comerțului lipsește încă sau Dazr analizează documentele. method arată ce cale a fost începută, de exemplu qes (reprezentantul semnează declarația), qseal, pec, letter, video sau documents. |
verified | Verificată. method este qes_org (semnătură calificată, certificatul numește organizația), extract_sealed (semnătură calificată sau act de identitate analizat, plus un extras sigilat de registrul comerțului), qes_reviewed (semnătură calificată, extras verificat de Dazr), qseal (sigiliul electronic calificat al organizației), documents, pec (un cod trimis la adresa PEC a organizației, Italia), letter (un cod trimis prin poștă la sediul social), video (un apel video cu Dazr) sau extract. authority arată ce a dovedit că persoana reprezintă organizația (vedeți mai jos), iar verified_at este un timp Unix. |
Doar când statutul este verified, verification.authority (și authority în webhookuri) arată cum a fost dovedită legătura dintre persoană și organizație:
| verification.authority | Semnificație |
|---|---|
certificate | Certificatul calificat al semnatarului sau sigiliul calificat al organizației numește organizația cu numărul său de înregistrare. Când certificatul conține doar codul de TVA, un extras din registru a dovedit numărul de înregistrare. |
register_extract | Un extras sigilat de registrul comerțului, cu o vechime de cel mult 3 luni, numește organizația cu numărul de înregistrare și codul de TVA și îl menționează pe semnatar ca administrator sau reprezentant legal. |
reviewed | Dazr a verificat un extras care îl menționează pe semnatar sau, fără semnătură calificată, extrasul și un act de identitate. |
pec | Un cod trimis la adresa PEC din visura sigilată de registru (Italia). |
letter | Un cod trimis prin poștă la sediul social, după ce Dazr a verificat datele în raport cu registrul. |
video | Un apel video cu Dazr: un act de identitate și un extras oficial care menționează persoana. |
Valoarea booleană verified rămâne pentru compatibilitate și este egală cu verification.status === 'verified'. Fiecare organizație are și un id, același pe care îl folosesc webhookurile.
Când statutul este pending sau verified, verification.report_url este adresa raportului de verificare.
"organisations": [{
"id": "org_3k9x2m0q8w1v5t7a", "name": "Conti Logistica S.r.l.", "country": "IT",
"register_number": "REA MI1234567", "vat": "IT12345678903", "vat_verified": true,
"display_name": "Conti", "website": "https://conti.example",
"verified": false, "verification": { "status": "pending", "method": "qes" }, "role": "owner"
}]
role și apartenența sunt citite din nou la fiecare reîmprospătare a tokenului și la fiecare cerere de informații despre utilizator: după o schimbare de rol, următorul răspuns conține noul rol, iar o organizație pe care persoana a părăsit-o sau din care a fost eliminată nu mai este inclusă. Când un administrator al organizației deconectează aplicația dumneavoastră, organizația este omisă din tokenurile emise anterior, până când un membru o partajează din nou cu aplicația într-o nouă autentificare. display_name și website sunt null când organizația nu le-a setat; name este întotdeauna denumirea legală.
Cereți o organizație verificată
În consolă, setați Cereți o organizație verificată la Verificare începută sau Verificată ori cereți per solicitare cu acr_values=urn:dazr:org:verification-started sau acr_values=urn:dazr:org:verified (câștigă cea mai strictă dintre ele). Aplicația trebuie să ceară și domeniul de acces organisations.

Cineva fără o organizație eligibilă este condus prin proces în aceeași autentificare: numele său, organizația (cu codul de TVA verificat în VIES), apoi verificarea. Poate semna imediat, poate primi declarația pe e-mail sau poate numi pe altcineva care să semneze. Apoi bifează organizația pe ecranul de consimțământ (pot fi bifate doar organizațiile eligibile) și revine la URI-ul de redirecționare.
Dacă altcineva mai trebuie să semneze, persoana revine cu statutul pending, chiar și când ați cerut Verificată: primiți un cod, claimul spune pending, iar acr din tokenul ID este urn:dazr:org:verification-started în loc de urn:dazr:org:verified. Decideți întotdeauna pe baza verification.status, niciodată pe baza faptului că autentificarea a reușit. Cu prompt=none primiți interaction_required când cerința nu este îndeplinită.
Modificările setării se aplică de la următoarea autentificare. Persoanele deja autentificate nu sunt deconectate: răspunsurile la reîmprospătare, endpointul de informații despre utilizator și webhookurile conțin întotdeauna statutul curent, așa că folosiți-le pentru a reacționa în sesiunile existente.
Webhookuri
Adăugați un URL de webhook (https) în consolă. Vedeți secretul de semnare o singură dată; îl puteți roti. Dazr trimite organisation.verification.updated când o organizație pe care unul dintre utilizatori a partajat-o cu aplicația dumneavoastră devine pending, verified, failed sau unverified. Aplicațiile care nu au primit niciodată o organizație prin consimțământ nu află nimic despre ea.
POST /your/webhook
Content-Type: application/json
Dazr-Event: organisation.verification.updated
Dazr-Delivery: dlv_8Fq2…
Dazr-Signature: t=1791021600,v1=5e0c…
{ "id": "evt_…", "type": "organisation.verification.updated", "created": 1791021600,
"data": { "organisation": { "id": "org_3k9x2m0q8w1v5t7a", "name": "Conti Logistica S.r.l.", "country": "IT" },
"status": "verified", "method": "qes_org", "authority": "certificate", "verified_at": 1791021598,
"report_url": "https://identity.dazr.eu/oauth/verification-report?org=org_3k9x2m0q8w1v5t7a",
"subjects": ["Xo1c…"] } }
status este pending, verified, failed sau unverified. subjects sunt valorile sub, în aplicația dumneavoastră, ale persoanelor care au partajat această organizație cu ea. Verificați semnătura înainte să aveți încredere în conținut:
import crypto from 'node:crypto';
// raw = the request body exactly as received (a string), header = the Dazr-Signature header
function verifyDazrSignature(raw, header, secret) {
const m = /^t=(\d+),v1=([a-f0-9]{64})$/.exec(header || '');
if (!m || Math.abs(Date.now() / 1000 - Number(m[1])) > 300) return false; // reject old deliveries
const want = crypto.createHmac('sha256', secret).update(m[1] + '.' + raw).digest('hex');
return crypto.timingSafeEqual(Buffer.from(want), Buffer.from(m[2]));
}
Răspundeți cu orice cod 2xx în 8 secunde. Altfel, Dazr reîncearcă după aproximativ 5 minute, 30 de minute, 2, 6, 12 și 24 de ore, apoi marchează livrarea ca eșuată. Fiecare încercare are același ID Dazr-Delivery, așa că ignorați duplicatele. Consola listează livrările recente, poate retrimite una și poate trimite un eveniment de test (webhook.test). Funcționează și interogarea periodică a endpointului de informații despre utilizator.
Rapoarte de verificare pentru audituri
Pentru fiecare organizație partajată cu aplicația dumneavoastră puteți obține un raport despre cum și când a verificat-o Dazr, pentru dosarul de audit. Există cât timp organizația este verificată și cât timp verificarea este în curs, arătând ce s-a făcut până atunci.
- Organizația: nume, țară, număr de înregistrare, cod de TVA și sediu social.
- Verificarea: statut, metodă, autoritate și când a fost cerută, semnată și verificată.
- Dovezile: pentru o semnătură sau un sigiliu calificat, numele semnatarului din certificat, emitentul certificatului, numărul de serie, valabilitatea și amprenta SHA-256, statutul său calificat (declarațiile QC, prestatorul și serviciul de încredere din lista de încredere a UE, cu numărul de secvență și data emiterii listei), momentul semnării și verificarea revocării. Pentru un extras sigilat de registru, cine l-a sigilat, când și ce a corespuns: nume, număr de înregistrare, cod de TVA, administrator. Rezultatul VIES. Pentru un cod PEC, o scrisoare sau un apel video, datele și verificările bifate de un evaluator Dazr, afișat ca „Evaluator Dazr” cu un ID intern.
- Pentru dosarele dumneavoastră: amprenta SHA-256 a fiecărui fișier de dovadă, un ID al documentului, momentul generării raportului și o scurtă explicație a fiecărei metode și a ceea ce înseamnă autoritatea.
Un raport nu conține niciodată imagini sau numere ale actelor de identitate, coduri unice, adresa PEC, adrese de e-mail sau vreo altă adresă în afară de sediul social.
Obțineți un raport
Autentificați-vă cu ID-ul și secretul clientului, ca la endpointul de token: HTTP Basic (client_secret_basic) sau corpul formularului unui POST (client_secret_post). Nu puneți niciodată secretul în URL. Folosiți id-ul organizației din claimuri sau webhookuri ori pur și simplu verification.report_url pe care îl conțin.
curl -u "$DAZR_CLIENT_ID:$DAZR_CLIENT_SECRET" -o report.pdf \
"https://identity.dazr.eu/oauth/verification-report?org=org_3k9x2m0q8w1v5t7a&format=pdf&lang=en"
| Parametru | Semnificație |
|---|---|
org | id-ul organizației. |
format | pdf (implicit) sau jws, aceleași fapte ca JSON semnat. |
lang | Limba PDF-ului: en (implicit), nl, it, de, fr, es sau pl. |
doc | În locul raportului: declaration, declarația semnată a administratorului (doar semnătură sau sigiliu calificat), ori extract, extrasul din registrul comerțului. |
Pot fi obținute doar organizațiile pe care cel puțin unul dintre utilizatori le-a partajat cu aplicația prin consimțământ. Orice altă organizație răspunde 404, la fel ca una care nu există sau nu are verificare; un secret de client greșit răspunde 401. Aplicațiile fără secret de client nu pot obține rapoarte. Descărcările au limite de frecvență și fiecare apare în activitatea organizației pentru administratorii ei, cu numele aplicației dumneavoastră. În consolă, pagina aplicației listează organizațiile conectate, cu aceleași descărcări.
Verificați JSON-ul semnat
Cu format=jws primiți un JWS compact (ES256, antet typ dazr-verification-report+jwt), semnat cu aceleași chei ca tokenurile ID. Claimurile sale sunt iss, iat, jti (ID-ul documentului), sub (id-ul organizației), aud (ID-ul dumneavoastră de client) și report, faptele. PDF-ul conține același JWS pe ultima pagină și în metadate (DazrVerificationReport), așa că și un PDF poate fi verificat offline.
import { createRemoteJWKSet, jwtVerify } from 'jose';
const jwks = createRemoteJWKSet(new URL('https://identity.dazr.eu/oauth/jwks'));
// jws = the response body of format=jws, or the text from the PDF metadata
const { payload } = await jwtVerify(jws, jwks, {
issuer: 'https://identity.dazr.eu',
audience: process.env.DAZR_CLIENT_ID,
typ: 'dazr-verification-report+jwt',
});
console.log(payload.report.verification.status, payload.report.verification.authority);
Lăsați un auditor să verifice semnătura
Pentru o semnătură sau un sigiliu calificat, doc=declaration returnează declarația semnată exact așa cum a fost încărcată: un PDF semnat (PAdES) sau un fișier .p7m (CAdES). Un auditor o poate valida independent cu validatorul demonstrativ DSS al Comisiei Europene: încărcați fișierul, păstrați politica de validare implicită și rulați. Rezultatul arată dacă semnătura este calificată (QESig sau QESeal pentru un sigiliu), cine a semnat și prestatorul de servicii de încredere din lista de încredere a UE. doc=extract returnează extrasul din registrul comerțului; un extras sigilat de registru poate fi validat în același mod.
Raportul este o dovadă pentru dosarul de audit. Firmele reglementate rămân responsabile pentru propria verificare a clienților.
Dazr păstrează declarația semnată, extrasul și datele raportului cât timp organizația este verificată și timp de 5 ani după încheierea verificării sau ștergerea organizației. Păstrați propriile copii atât timp cât o cer regulile dumneavoastră.
Tokenuri și durate de valabilitate
| Token | Durată de valabilitate și reguli |
|---|---|
| Cod de autorizare | 60 de secunde, de unică folosință, legat de clientul, URI-ul de redirecționare și provocarea PKCE. Folosirea unui cod de două ori revocă tokenurile emise cu el. |
| Token de acces | 10 minute. Un JWT semnat (ES256, typ at+jwt) cu aud = ID-ul dumneavoastră de client. Trimiteți-l ca Authorization: Bearer. |
| Token ID | 10 minute. ES256, cu iss, sub, aud, exp, iat, auth_time, nonce și amr acolo unde sunt cunoscute. |
| Token de reîmprospătare | Doar cu offline_access. Se rotește la fiecare utilizare: stocați întotdeauna noul token. Retrimiterea unui token de reîmprospătare vechi revocă întreaga autentificare. Expiră după 30 de zile de neutilizare și după cel mult 180 de zile. |
Cheile de semnare se rotesc. Alegeți întotdeauna cheia după kid din JWKS și reîmprospătați JWKS când vedeți un kid necunoscut.
Erori
Cât timp ID-ul clientului și URI-ul de redirecționare sunt valide, erorile revin la URI-ul de redirecționare ca error, error_description, state și iss: de exemplu invalid_request (cum ar fi PKCE lipsă sau plain), invalid_scope, unsupported_response_type, access_denied (persoana a anulat sau aplicația este în testare și persoana nu este membru), login_required, consent_required și interaction_required (cu prompt=none, când lipsește o organizație verificată cerută). Cu un client necunoscut sau un URI de redirecționare neînregistrat, Dazr afișează o pagină de eroare și nu redirecționează niciodată. Endpointul de token răspunde cu erori JSON precum invalid_client, invalid_grant și unsupported_grant_type.
Deconectare
Pentru a deconecta pe cineva, trimiteți persoana la endpointul de deconectare cu id_token_hint (sau client_id), un post_logout_redirect_uri opțional înregistrat în setările aplicației și state. Dazr o întreabă dacă vrea să se deconecteze și din Dazr Identity pe acel dispozitiv, apoi o trimite înapoi. Revocați tokenurile de reîmprospătare de care nu mai aveți nevoie la endpointul de revocare.
Testare și lansare
O aplicație nouă este în testare: doar membrii organizației dumneavoastră se pot autentifica, iar ecranul de consimțământ menționează acest lucru. Pentru lansare, verificați organizația în Dazr Identity, adăugați un URI de redirecționare https:// și solicitați o evaluare pentru lansare în consolă. Schimbarea numelui, scopului, politicii de confidențialității sau datelor unei aplicații lansate necesită o nouă evaluare.
Transferul unei aplicații către altă organizație
O aplicație poate trece la altă organizație înregistrată pe Dazr, de exemplu după o vânzare sau o reorganizare. Un proprietar sau administrator pornește transferul din Transferați aplicația, în setările aplicației, în Dazr Identity sau în portalul Sign. Un proprietar sau administrator al celeilalte organizații îl acceptă sau îl refuză în 14 zile. Până atunci, expeditorul poate anula și nu se schimbă nimic.
- Cine o poate primi. Doar o organizație înregistrată pe Dazr, indicată prin ID-ul organizației. Proprietarii și administratorii ei găsesc ID-ul în datele juridice din Dazr Identity. O aplicație activă, o aplicație în analiză, o aplicație care necesită o organizație verificată și o aplicație cu API-ul Dazr Sign activat pot trece doar la o organizație verificată. Acest lucru se verifică din nou când transferul este acceptat.
- O autentificare recentă. Pornirea și acceptarea unui transfer necesită o autentificare din ultimele 10 minute.
- Ce se mută. Client ID-ul, setările, logoul, URI-urile de redirecționare, API-urile activate și URL-urile webhookurilor. Administratorul care acceptă acceptă și Termenii pentru dezvoltatori în numele noii organizații.
- Client secretul. O aplicație web server primește un nou client secret, afișat o singură dată administratorului care acceptă. Secretul anterior continuă să funcționeze la endpointurile de token, revocare și introspecție pe durata perioadei de grație alese la pornirea transferului: niciuna, 24 de ore (implicit) sau 7 zile. Rapoartele de verificare necesită noul secret.
- Webhookuri. URL-urile rămân. Secretele lor de semnare, pentru Dazr Identity și pentru Dazr Sign, sunt reînnoite și afișate o singură dată administratorului care acceptă. Livrările de dinainte de transfer nu sunt retrimise.
- Persoanele și
sub-ul lor. Fiecare persoană își păstrează acelașisubîn aplicație, așa că conturile din aplicația dumneavoastră continuă să funcționeze. Diferă desub-ul persoanei în celelalte aplicații ale noii organizații. Persoanele aprobă din nou aplicația la următoarea autentificare, deoarece ecranul de consimțământ numește acum noua organizație. Tokenurile emise înainte de transfer nu mai funcționează. - Ce rămâne la proprietarul anterior. Numărul de autentificări și de consimțăminte și livrările webhookurilor de dinainte de transfer. Documentele create prin API-ul Dazr Sign rămân la persoanele cărora le aparțin, iar noul proprietar al aplicației nu le poate vedea.
Butonul
Folosiți formularea „Sign in with Dazr Identity” și logoul Dazr ca mai jos. Puteți schimba dimensiunea, nu și logoul, culorile sau formularea. Legați-l de propria rută care pornește fluxul.
<a href="/auth/dazr" style="display:inline-flex;align-items:center;gap:10px;height:44px;padding:0 18px;border-radius:22px;background:#18203a;color:#fff;font: 600 15px/1 'Dazr', system-ui, sans-serif;text-decoration:none">
<svg width="20" height="20" viewBox="0 0 100 100" aria-hidden="true"><path d="M50 4 89 16v31c0 25.5-16.8 42.5-39 50C27.8 89.5 11 72.5 11 47V16z" fill="#fff"/><path d="M50 15.5 79 24.5v22.8c0 19.5-12.4 32.6-29 38.7C33.4 79.9 21 66.8 21 47.3V24.5z" fill="#18203a"/><path d="M50 24 71 30.6v16.9c0 14.5-9 24.4-21 29.2-12-4.8-21-14.7-21-29.2V30.6z" fill="#fff"/></svg>
Sign in with Dazr Identity
</a>
Fontul Dazr. Butonul folosește fontul Dazr, care poate fi folosit gratuit sub licența SIL Open Font License. Acolo unde Dazr nu este încărcat, se folosește în schimb fontul sistemului. Descărcați fontul Dazr (ZIP cu fișiere TTF și WOFF2) pentru a-l găzdui pe propriul site:
/* woff2 files from the ZIP, copied to /fonts/ on your site */
@font-face { font-family: 'Dazr'; font-weight: 400; font-display: swap;
src: url('/fonts/dazr-regular-latin.woff2') format('woff2'); }
@font-face { font-family: 'Dazr'; font-weight: 700; font-display: swap;
src: url('/fonts/dazr-bold-latin.woff2') format('woff2'); }
.dazr-signin { font: 600 15px/1 'Dazr', system-ui, sans-serif; }
Un exemplu minimal în Node.js
Node 18 sau mai nou, fără dependențe. O aplicație cu server web cu secret de client; pentru un client public, eliminați antetul Authorization și trimiteți client_id în corp.
import crypto from 'node:crypto';
const issuer = 'https://identity.dazr.eu';
const clientId = process.env.DAZR_CLIENT_ID;
const clientSecret = process.env.DAZR_CLIENT_SECRET;
const redirectUri = 'https://app.example.eu/auth/dazr/callback';
const b64url = (buf) => Buffer.from(buf).toString('base64url');
// 1. Start: keep verifier, state and nonce in the user's session.
export function start(session) {
session.verifier = b64url(crypto.randomBytes(32));
session.state = b64url(crypto.randomBytes(16));
session.nonce = b64url(crypto.randomBytes(16));
const challenge = b64url(crypto.createHash('sha256').update(session.verifier).digest());
return issuer + '/oauth/authorize?' + new URLSearchParams({
response_type: 'code', client_id: clientId, redirect_uri: redirectUri,
scope: 'openid profile email', state: session.state, nonce: session.nonce,
code_challenge: challenge, code_challenge_method: 'S256',
});
}
// 2. Callback: check state, exchange the code, verify the ID token.
export async function callback(session, query) {
if (query.error) throw new Error('sign-in failed: ' + query.error);
if (query.state !== session.state || query.iss !== issuer) throw new Error('state or issuer mismatch');
const res = await fetch(issuer + '/oauth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: 'Basic ' + Buffer.from(clientId + ':' + clientSecret).toString('base64'),
},
body: new URLSearchParams({ grant_type: 'authorization_code', code: query.code, redirect_uri: redirectUri, code_verifier: session.verifier }),
});
const tokens = await res.json();
if (!res.ok) throw new Error(tokens.error);
const claims = await verifyIdToken(tokens.id_token, session.nonce);
return { sub: claims.sub, email: claims.email, name: claims.name, tokens };
}
async function verifyIdToken(idToken, nonce) {
const [h, p, s] = idToken.split('.');
const header = JSON.parse(Buffer.from(h, 'base64url'));
const { keys } = await (await fetch(issuer + '/oauth/jwks')).json();
const jwk = keys.find((k) => k.kid === header.kid);
if (!jwk || header.alg !== 'ES256') throw new Error('unknown signing key');
const ok = crypto.verify('sha256', Buffer.from(h + '.' + p),
{ key: crypto.createPublicKey({ key: jwk, format: 'jwk' }), dsaEncoding: 'ieee-p1363' }, Buffer.from(s, 'base64url'));
const c = JSON.parse(Buffer.from(p, 'base64url'));
const now = Math.floor(Date.now() / 1000);
if (!ok || c.iss !== issuer || c.aud !== clientId || c.exp < now - 30 || c.nonce !== nonce) throw new Error('invalid ID token');
return c;
}
Limite
Endpointurile de autorizare și de token au limite de frecvență. Dacă primiți HTTP 429, așteptați și încercați din nou; nu reîncercați într-o buclă strânsă.
Obligațiile dumneavoastră
Organizația dumneavoastră este operator independent pentru datele pe care le primește. Termenii pentru dezvoltatori Dazr Identity stabilesc ce puteți face cu ele, cum le păstrați în siguranță și cum raportați încălcările. Întrebări: hello@dazr.eu.